<!DOCTYPE HTML>
<html lang="zh-CN">


<head>
    <meta charset="utf-8">
    <meta name="keywords" content="Gin框架中文文档, 双的鱼 双的鱼博客 hexo博客 个人博客">
    <meta name="description" content="双的鱼博客，记录我的学习和感想">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <meta name="renderer" content="webkit|ie-stand|ie-comp">
    <meta name="mobile-web-app-capable" content="yes">
    <meta name="format-detection" content="telephone=no">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
    <meta name="referrer" content="no-referrer" />
    <!-- Global site tag (gtag.js) - Google Analytics -->


    <title>Gin框架中文文档 | 双的鱼博客</title>
    <link rel="icon" type="image/png" href="/images/logo.png">

    <link rel="stylesheet" type="text/css" href="/libs/awesome/css/all.css">
    <link rel="stylesheet" type="text/css" href="/libs/materialize/materialize.min.css">
    <link rel="stylesheet" type="text/css" href="/libs/aos/aos.css">
    <link rel="stylesheet" type="text/css" href="/libs/animate/animate.min.css">
    <link rel="stylesheet" type="text/css" href="/libs/lightGallery/css/lightgallery.min.css">
    <link rel="stylesheet" type="text/css" href="/css/matery.css">
    <link rel="stylesheet" type="text/css" href="/css/my.css">

    <script src="/libs/jquery/jquery.min.js"></script>

<meta name="generator" content="Hexo 6.3.0"><link rel="alternate" href="/atom.xml" title="双的鱼博客" type="application/atom+xml">
</head>




<body>
    <header class="navbar-fixed">
    <nav id="headNav" class="bg-color nav-transparent">
        <div id="navContainer" class="nav-wrapper container">
            <div class="brand-logo">
                <a href="/" class="waves-effect waves-light">
                    
                    <img src="/images/logo.png" class="logo-img" alt="LOGO">
                    
                    <span class="logo-span">双的鱼博客</span>
                </a>
            </div>
            

<a href="#" data-target="mobile-nav" class="sidenav-trigger button-collapse"><i class="fas fa-bars"></i></a>
<ul class="right nav-menu">
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/" class="waves-effect waves-light">
      
      <i class="fas fa-home" style="zoom: 0.6;"></i>
      
      <span>首页</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/tags" class="waves-effect waves-light">
      
      <i class="fas fa-tags" style="zoom: 0.6;"></i>
      
      <span>标签</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/categories" class="waves-effect waves-light">
      
      <i class="fas fa-bookmark" style="zoom: 0.6;"></i>
      
      <span>分类</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/archives" class="waves-effect waves-light">
      
      <i class="fas fa-archive" style="zoom: 0.6;"></i>
      
      <span>归档</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/weibo" class="waves-effect waves-light">
      
      <i class="fa fa-comment" style="zoom: 0.6;"></i>
      
      <span>微博</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/album" class="waves-effect waves-light">
      
      <i class="fa fa-camera-retro" style="zoom: 0.6;"></i>
      
      <span>相册</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/about" class="waves-effect waves-light">
      
      <i class="fas fa-user-circle" style="zoom: 0.6;"></i>
      
      <span>关于</span>
    </a>
    
  </li>
  
  <li>
    <a href="#searchModal" class="modal-trigger waves-effect waves-light">
      <i id="searchIcon" class="fas fa-search" title="搜索" style="zoom: 0.85;"></i>
    </a>
  </li>
</ul>


<div id="mobile-nav" class="side-nav sidenav">

    <div class="mobile-head bg-color">
        
        <img src="/images/logo.png" class="logo-img circle responsive-img">
        
        <div class="logo-name">双的鱼博客</div>
        <div class="logo-desc">
            
            双的鱼博客，记录我的学习和感想
            
        </div>
    </div>

    

    <ul class="menu-list mobile-menu-list">
        
        <li class="m-nav-item">
	  
		<a href="/" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-home"></i>
			
			首页
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/tags" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-tags"></i>
			
			标签
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/categories" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-bookmark"></i>
			
			分类
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/archives" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-archive"></i>
			
			归档
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/weibo" class="waves-effect waves-light">
			
			    <i class="fa-fw fa fa-comment"></i>
			
			微博
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/album" class="waves-effect waves-light">
			
			    <i class="fa-fw fa fa-camera-retro"></i>
			
			相册
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/about" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-user-circle"></i>
			
			关于
		</a>
          
        </li>
        
        
    </ul>
</div>


        </div>

        
    </nav>

</header>

    
<script src="/libs/cryptojs/crypto-js.min.js"></script>
<script>
    (function() {
        let pwd = '';
        if (pwd && pwd.length > 0) {
            if (pwd !== CryptoJS.SHA256(prompt('请输入访问本文章的密码')).toString(CryptoJS.enc.Hex)) {
                alert('密码错误，将返回主页！');
                location.href = '/';
            }
        }
    })();
</script>




<div class="bg-cover pd-header post-cover" style="background-image: url('/gallery/gin.jpg')">
    <div class="container" style="right: 0px;left: 0px;">
        <div class="row">
            <div class="col s12 m12 l12">
                <div class="brand">
                    <h1 class="description center-align post-title">Gin框架中文文档</h1>
                </div>
            </div>
        </div>
    </div>
</div>




<main class="post-container content">

    
    <link rel="stylesheet" href="/libs/tocbot/tocbot.css">
<style>
    #articleContent h1::before,
    #articleContent h2::before,
    #articleContent h3::before,
    #articleContent h4::before,
    #articleContent h5::before,
    #articleContent h6::before {
        display: block;
        content: " ";
        height: 100px;
        margin-top: -100px;
        visibility: hidden;
    }

    #articleContent :focus {
        outline: none;
    }

    .toc-fixed {
        position: fixed;
        top: 64px;
    }

    .toc-widget {
        width: 345px;
        padding-left: 20px;
        height: auto;
    }

    .toc-widget .toc-title {
        padding: 35px 0 15px 17px;
        font-size: 1.5rem;
        font-weight: bold;
        line-height: 1.5rem;
    }

    .toc-widget ol {
        padding: 0;
        list-style: none;
    }

    #toc-content {
        padding-bottom: 30px;
        overflow: auto;
        max-height: calc(100vh - 10rem);
    }

    #toc-content ol {
        padding-left: 10px;
        overflow: auto;
    }

    #toc-content ol li {
        padding-left: 10px;
    }

    #toc-content .toc-link:hover {
        color: #42b983;
        font-weight: 700;
        text-decoration: underline;
    }

    #toc-content .toc-link::before {
        background-color: transparent;
        max-height: 25px;

        position: absolute;
        right: 23.5vw;
        display: block;
    }

    #toc-content .is-active-link {
        color: #42b983;
    }

    #floating-toc-btn {
        position: fixed;
        right: 15px;
        bottom: 76px;
        padding-top: 15px;
        margin-bottom: 0;
        z-index: 998;
    }

    #floating-toc-btn .btn-floating {
        width: 48px;
        height: 48px;
    }

    #floating-toc-btn .btn-floating i {
        line-height: 48px;
        font-size: 1.4rem;
    }
</style>
<div class="row">
    <div id="main-content" class="col s12 m12 l9">
        <!-- 文章内容详情 -->
<div id="artDetail">
    <div class="card">
        <div class="card-content article-info">
            <div class="row tag-cate">
                <div class="col s7">
                    
                    <div class="article-tag">
                        
                            <a href="/tags/Go/">
                                <span class="chip bg-color">Go</span>
                            </a>
                        
                            <a href="/tags/Gin/">
                                <span class="chip bg-color">Gin</span>
                            </a>
                        
                    </div>
                    
                </div>
                <div class="col s5 right-align">
                    
                    <div class="post-cate">
                        <i class="fas fa-bookmark fa-fw icon-category"></i>
                        
                            <a href="/categories/%E6%8A%80%E6%9C%AF/" class="post-category">
                                技术
                            </a>
                        
                    </div>
                    
                </div>
            </div>

            <div class="post-info">
                
                <div class="post-date info-break-policy">
                    <i class="far fa-calendar-minus fa-fw"></i>发布日期:&nbsp;&nbsp;
                    2018-06-08
                </div>
                

                

                
                <div class="info-break-policy">
                    <i class="far fa-file-word fa-fw"></i>文章字数:&nbsp;&nbsp;
                    7.2k
                </div>
                

                
                <div class="info-break-policy">
                    <i class="far fa-clock fa-fw"></i>阅读时长:&nbsp;&nbsp;
                    38 分
                </div>
                

                
            </div>
        </div>
        <hr class="clearfix">

        
        <!-- 是否加载使用自带的 prismjs. -->
        <link rel="stylesheet" href="/libs/prism/prism.css">
        

        

        <div class="card-content article-card-content">
            <div id="articleContent">
                <p><strong>最近更新时间：2019-02-20</strong></p>
<p>另附看云<a target="_blank" rel="noopener" href="https://www.kancloud.cn/shuangdeyu/gin_book/949411">地址</a></p>
<hr>
<p>Gin 是一个 go 写的 web 框架，具有高性能的优点。官方地址：<a target="_blank" rel="noopener" href="https://github.com/gin-gonic/gin">https://github.com/gin-gonic/gin</a></p>
<p><strong>目录</strong></p>
<h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><p>要安装Gin包，首先需要安装Go并设置Go工作区</p>
<p>1、下载并安装</p>
<blockquote>
<p>$ go get -u github.com/gin-gonic/gin</p>
</blockquote>
<p>2、在代码中导入它</p>
<blockquote>
<p>import “github.com/gin-gonic/gin”</p>
</blockquote>
<p><strong>使用包管理工具Govendor安装</strong></p>
<p>1、<code>go get</code> govendor(安装)</p>
<blockquote>
<p>$ go get github.com/kardianos/govendor</p>
</blockquote>
<p>2、创建项目文件夹并进入文件夹</p>
<blockquote>
<p>$ mkdir -p $GOPATH/src/github.com/myusername/project &amp;&amp; cd “$_”</p>
</blockquote>
<p>3、初始化项目并添加 gin</p>
<blockquote>
<p>$ govendor init</p>
<p>$ govendor fetch github.com/gin-gonic/gin@v1.3</p>
</blockquote>
<p>4、复制一个模板到你的项目</p>
<blockquote>
<p>$ curl <a target="_blank" rel="noopener" href="https://raw.githubusercontent.com/gin-gonic/gin/master/examples/basic/main.go">https://raw.githubusercontent.com/gin-gonic/gin/master/examples/basic/main.go</a> &gt; main.go</p>
</blockquote>
<p>5、运行项目</p>
<blockquote>
<p>$ go run main.go</p>
</blockquote>
<h2 id="前提"><a href="#前提" class="headerlink" title="前提"></a>前提</h2><p>使用gin需要Go的版本号为1.6或更高</p>
<h2 id="快速入门"><a href="#快速入门" class="headerlink" title="快速入门"></a>快速入门</h2><p>运行这段代码并在浏览器中访问 <a target="_blank" rel="noopener" href="http://localhost:8080/">http://localhost:8080</a></p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">package</span> main

<span class="token keyword">import</span> <span class="token string">"github.com/gin-gonic/gin"</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/ping"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span>
			<span class="token string">"message"</span><span class="token punctuation">:</span> <span class="token string">"pong"</span><span class="token punctuation">,</span>
		<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
	r<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// listen and serve on 0.0.0.0:8080</span>
<span class="token punctuation">&#125;</span></code></pre>

<h2 id="代码示例"><a href="#代码示例" class="headerlink" title="代码示例"></a>代码示例</h2><h3 id="使用-GET-POST-PUT-PATCH-DELETE-OPTIONS"><a href="#使用-GET-POST-PUT-PATCH-DELETE-OPTIONS" class="headerlink" title="使用 GET, POST, PUT, PATCH, DELETE, OPTIONS"></a>使用 GET, POST, PUT, PATCH, DELETE, OPTIONS</h3><pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	<span class="token comment">// Disable Console Color</span>
	<span class="token comment">// gin.DisableConsoleColor()</span>

	<span class="token comment">// 使用默认中间件创建一个gin路由器</span>
	<span class="token comment">// logger and recovery (crash-free) 中间件</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	router<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/someGet"</span><span class="token punctuation">,</span> getting<span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">"/somePost"</span><span class="token punctuation">,</span> posting<span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">PUT</span><span class="token punctuation">(</span><span class="token string">"/somePut"</span><span class="token punctuation">,</span> putting<span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">DELETE</span><span class="token punctuation">(</span><span class="token string">"/someDelete"</span><span class="token punctuation">,</span> deleting<span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">PATCH</span><span class="token punctuation">(</span><span class="token string">"/somePatch"</span><span class="token punctuation">,</span> patching<span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">HEAD</span><span class="token punctuation">(</span><span class="token string">"/someHead"</span><span class="token punctuation">,</span> head<span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">OPTIONS</span><span class="token punctuation">(</span><span class="token string">"/someOptions"</span><span class="token punctuation">,</span> options<span class="token punctuation">)</span>

	<span class="token comment">// 默认启动的是 8080端口，也可以自己定义启动端口</span>
	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	<span class="token comment">// router.Run(":3000") for a hard coded port</span>
<span class="token punctuation">&#125;</span></code></pre>

<h3 id="获取路径中的参数"><a href="#获取路径中的参数" class="headerlink" title="获取路径中的参数"></a>获取路径中的参数</h3><pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	<span class="token comment">// 此规则能够匹配/user/john这种格式，但不能匹配/user/ 或 /user这种格式</span>
	router<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/user/:name"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		name <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">Param</span><span class="token punctuation">(</span><span class="token string">"name"</span><span class="token punctuation">)</span>
		c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">"Hello %s"</span><span class="token punctuation">,</span> name<span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

	<span class="token comment">// 但是，这个规则既能匹配/user/john/格式也能匹配/user/john/send这种格式</span>
	<span class="token comment">// 如果没有其他路由器匹配/user/john，它将重定向到/user/john/</span>
	router<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/user/:name/*action"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		name <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">Param</span><span class="token punctuation">(</span><span class="token string">"name"</span><span class="token punctuation">)</span>
		action <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">Param</span><span class="token punctuation">(</span><span class="token string">"action"</span><span class="token punctuation">)</span>
		message <span class="token operator">:=</span> name <span class="token operator">+</span> <span class="token string">" is "</span> <span class="token operator">+</span> action
		c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> message<span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">":8080"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<h3 id="获取Get参数"><a href="#获取Get参数" class="headerlink" title="获取Get参数"></a>获取Get参数</h3><pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	<span class="token comment">// 匹配的url格式:  /welcome?firstname=Jane&amp;lastname=Doe</span>
	router<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/welcome"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		firstname <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">DefaultQuery</span><span class="token punctuation">(</span><span class="token string">"firstname"</span><span class="token punctuation">,</span> <span class="token string">"Guest"</span><span class="token punctuation">)</span>
		lastname <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">Query</span><span class="token punctuation">(</span><span class="token string">"lastname"</span><span class="token punctuation">)</span> <span class="token comment">// 是 c.Request.URL.Query().Get("lastname") 的简写</span>

		c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">"Hello %s %s"</span><span class="token punctuation">,</span> firstname<span class="token punctuation">,</span> lastname<span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">":8080"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<h3 id="获取Post参数"><a href="#获取Post参数" class="headerlink" title="获取Post参数"></a>获取Post参数</h3><pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	router<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">"/form_post"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		message <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">PostForm</span><span class="token punctuation">(</span><span class="token string">"message"</span><span class="token punctuation">)</span>
		nick <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">DefaultPostForm</span><span class="token punctuation">(</span><span class="token string">"nick"</span><span class="token punctuation">,</span> <span class="token string">"anonymous"</span><span class="token punctuation">)</span> <span class="token comment">// 此方法可以设置默认值</span>

		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span>
			<span class="token string">"status"</span><span class="token punctuation">:</span>  <span class="token string">"posted"</span><span class="token punctuation">,</span>
			<span class="token string">"message"</span><span class="token punctuation">:</span> message<span class="token punctuation">,</span>
			<span class="token string">"nick"</span><span class="token punctuation">:</span>    nick<span class="token punctuation">,</span>
		<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">":8080"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<h3 id="Get-Post-混合"><a href="#Get-Post-混合" class="headerlink" title="Get + Post 混合"></a>Get + Post 混合</h3><pre class="language-http" data-language="http"><code class="language-http">示例：
<span class="token request-line"><span class="token method property">POST</span> <span class="token request-target url">/post?id=1234&amp;page=1</span> <span class="token http-version property">HTTP/1.1</span></span>
<span class="token header"><span class="token header-name keyword">Content-Type</span><span class="token punctuation">:</span> <span class="token header-value">application/x-www-form-urlencoded</span></span>

name=manu&amp;message=this_is_great</code></pre>

<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	router<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">"/post"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>

		id <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">Query</span><span class="token punctuation">(</span><span class="token string">"id"</span><span class="token punctuation">)</span>
		page <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">DefaultQuery</span><span class="token punctuation">(</span><span class="token string">"page"</span><span class="token punctuation">,</span> <span class="token string">"0"</span><span class="token punctuation">)</span>
		name <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">PostForm</span><span class="token punctuation">(</span><span class="token string">"name"</span><span class="token punctuation">)</span>
		message <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">PostForm</span><span class="token punctuation">(</span><span class="token string">"message"</span><span class="token punctuation">)</span>

		fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"id: %s; page: %s; name: %s; message: %s"</span><span class="token punctuation">,</span> id<span class="token punctuation">,</span> page<span class="token punctuation">,</span> name<span class="token punctuation">,</span> message<span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">":8080"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<pre class="language-log" data-language="log"><code class="language-log">结果：id<span class="token operator">:</span> <span class="token number">1234</span><span class="token operator">;</span> page<span class="token operator">:</span> <span class="token number">1</span><span class="token operator">;</span> name<span class="token operator">:</span> manu<span class="token operator">;</span> message<span class="token operator">:</span> this_is_great</code></pre>


<h3 id="上传文件"><a href="#上传文件" class="headerlink" title="上传文件"></a>上传文件</h3><h4 id="单文件上传"><a href="#单文件上传" class="headerlink" title="单文件上传"></a>单文件上传</h4><p>参考问题 <a target="_blank" rel="noopener" href="https://github.com/gin-gonic/gin/issues/774">#774</a>，细节 <a target="_blank" rel="noopener" href="https://github.com/gin-gonic/gin/tree/master/examples/upload-file/single">example code</a></p>
<p>慎用 <code>file.Filename</code> ，参考 <a target="_blank" rel="noopener" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#Directives">Content-Disposition on MDN</a> 和 <a target="_blank" rel="noopener" href="https://github.com/gin-gonic/gin/issues/1693">#1693</a></p>
<blockquote>
<p>上传文件的文件名可以由用户自定义，所以可能包含非法字符串，为了安全起见，应该由服务端统一文件名规则</p>
</blockquote>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	<span class="token comment">// 给表单限制上传大小 (默认 32 MiB)</span>
	<span class="token comment">// router.MaxMultipartMemory = 8 &lt;&lt; 20  // 8 MiB</span>
	router<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">"/upload"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		<span class="token comment">// 单文件</span>
		file<span class="token punctuation">,</span> <span class="token boolean">_</span> <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">FormFile</span><span class="token punctuation">(</span><span class="token string">"file"</span><span class="token punctuation">)</span>
		log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>file<span class="token punctuation">.</span>Filename<span class="token punctuation">)</span>

		<span class="token comment">// 上传文件到指定的路径</span>
		<span class="token comment">// c.SaveUploadedFile(file, dst)</span>

		c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> fmt<span class="token punctuation">.</span><span class="token function">Sprintf</span><span class="token punctuation">(</span><span class="token string">"'%s' uploaded!"</span><span class="token punctuation">,</span> file<span class="token punctuation">.</span>Filename<span class="token punctuation">)</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">":8080"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<p><code>curl</code> 测试：</p>
<pre class="language-http" data-language="http"><code class="language-http">curl -X POST http://localhost:8080/upload \
  -F "file=@/Users/appleboy/test.zip" \
  -H "Content-Type: multipart/form-data"</code></pre>

<h4 id="多文件上传"><a href="#多文件上传" class="headerlink" title="多文件上传"></a>多文件上传</h4><p>详细示例：<a target="_blank" rel="noopener" href="https://github.com/gin-gonic/gin/tree/master/examples/upload-file/multiple">example code</a></p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	<span class="token comment">// 给表单限制上传大小 (默认 32 MiB)</span>
	<span class="token comment">// router.MaxMultipartMemory = 8 &lt;&lt; 20  // 8 MiB</span>
	router<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">"/upload"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		<span class="token comment">// 多文件</span>
		form<span class="token punctuation">,</span> <span class="token boolean">_</span> <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">MultipartForm</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
		files <span class="token operator">:=</span> form<span class="token punctuation">.</span>File<span class="token punctuation">[</span><span class="token string">"upload[]"</span><span class="token punctuation">]</span>

		<span class="token keyword">for</span> <span class="token boolean">_</span><span class="token punctuation">,</span> file <span class="token operator">:=</span> <span class="token keyword">range</span> files <span class="token punctuation">&#123;</span>
			log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>file<span class="token punctuation">.</span>Filename<span class="token punctuation">)</span>

			<span class="token comment">// 上传文件到指定的路径</span>
			<span class="token comment">// c.SaveUploadedFile(file, dst)</span>
		<span class="token punctuation">&#125;</span>
		c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> fmt<span class="token punctuation">.</span><span class="token function">Sprintf</span><span class="token punctuation">(</span><span class="token string">"%d files uploaded!"</span><span class="token punctuation">,</span> <span class="token function">len</span><span class="token punctuation">(</span>files<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">":8080"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<p><code>curl</code> 测试：</p>
<pre class="language-http" data-language="http"><code class="language-http">curl -X POST http://localhost:8080/upload \
  -F "upload[]=@/Users/appleboy/test1.zip" \
  -F "upload[]=@/Users/appleboy/test2.zip" \
  -H "Content-Type: multipart/form-data"</code></pre>

<h3 id="路由分组"><a href="#路由分组" class="headerlink" title="路由分组"></a>路由分组</h3><pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	<span class="token comment">// Simple group: v1</span>
	v1 <span class="token operator">:=</span> router<span class="token punctuation">.</span><span class="token function">Group</span><span class="token punctuation">(</span><span class="token string">"/v1"</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#123;</span>
		v1<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">"/login"</span><span class="token punctuation">,</span> loginEndpoint<span class="token punctuation">)</span>
		v1<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">"/submit"</span><span class="token punctuation">,</span> submitEndpoint<span class="token punctuation">)</span>
		v1<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">"/read"</span><span class="token punctuation">,</span> readEndpoint<span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span>

	<span class="token comment">// Simple group: v2</span>
	v2 <span class="token operator">:=</span> router<span class="token punctuation">.</span><span class="token function">Group</span><span class="token punctuation">(</span><span class="token string">"/v2"</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#123;</span>
		v2<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">"/login"</span><span class="token punctuation">,</span> loginEndpoint<span class="token punctuation">)</span>
		v2<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">"/submit"</span><span class="token punctuation">,</span> submitEndpoint<span class="token punctuation">)</span>
		v2<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">"/read"</span><span class="token punctuation">,</span> readEndpoint<span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span>

	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">":8080"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<h3 id="无中间件启动"><a href="#无中间件启动" class="headerlink" title="无中间件启动"></a>无中间件启动</h3><p>使用</p>
<pre class="language-go" data-language="go"><code class="language-go">r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span><span class="token punctuation">)</span></code></pre>

<p>代替</p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token comment">// 默认启动方式，包含 Logger、Recovery 中间件</span>
r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span></code></pre>

<h3 id="使用中间件"><a href="#使用中间件" class="headerlink" title="使用中间件"></a>使用中间件</h3><pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	<span class="token comment">// 创建一个不包含中间件的路由器</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	<span class="token comment">// 全局中间件</span>
	<span class="token comment">// 使用 Logger 中间件</span>
	r<span class="token punctuation">.</span><span class="token function">Use</span><span class="token punctuation">(</span>gin<span class="token punctuation">.</span><span class="token function">Logger</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>

	<span class="token comment">// 使用 Recovery 中间件</span>
	r<span class="token punctuation">.</span><span class="token function">Use</span><span class="token punctuation">(</span>gin<span class="token punctuation">.</span><span class="token function">Recovery</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>

	<span class="token comment">// 路由添加中间件，可以添加任意多个</span>
	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/benchmark"</span><span class="token punctuation">,</span> <span class="token function">MyBenchLogger</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> benchEndpoint<span class="token punctuation">)</span>

	<span class="token comment">// 路由组中添加中间件</span>
	<span class="token comment">// authorized := r.Group("/", AuthRequired())</span>
	<span class="token comment">// exactly the same as:</span>
	authorized <span class="token operator">:=</span> r<span class="token punctuation">.</span><span class="token function">Group</span><span class="token punctuation">(</span><span class="token string">"/"</span><span class="token punctuation">)</span>
	<span class="token comment">// per group middleware! in this case we use the custom created</span>
	<span class="token comment">// AuthRequired() middleware just in the "authorized" group.</span>
	authorized<span class="token punctuation">.</span><span class="token function">Use</span><span class="token punctuation">(</span><span class="token function">AuthRequired</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#123;</span>
		authorized<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">"/login"</span><span class="token punctuation">,</span> loginEndpoint<span class="token punctuation">)</span>
		authorized<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">"/submit"</span><span class="token punctuation">,</span> submitEndpoint<span class="token punctuation">)</span>
		authorized<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">"/read"</span><span class="token punctuation">,</span> readEndpoint<span class="token punctuation">)</span>

		<span class="token comment">// nested group</span>
		testing <span class="token operator">:=</span> authorized<span class="token punctuation">.</span><span class="token function">Group</span><span class="token punctuation">(</span><span class="token string">"testing"</span><span class="token punctuation">)</span>
		testing<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/analytics"</span><span class="token punctuation">,</span> analyticsEndpoint<span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span>

	<span class="token comment">// Listen and serve on 0.0.0.0:8080</span>
	r<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">":8080"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<h3 id="写日志文件"><a href="#写日志文件" class="headerlink" title="写日志文件"></a>写日志文件</h3><pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    <span class="token comment">// 禁用控制台颜色</span>
    gin<span class="token punctuation">.</span><span class="token function">DisableConsoleColor</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

    <span class="token comment">// 创建记录日志的文件</span>
    f<span class="token punctuation">,</span> <span class="token boolean">_</span> <span class="token operator">:=</span> os<span class="token punctuation">.</span><span class="token function">Create</span><span class="token punctuation">(</span><span class="token string">"gin.log"</span><span class="token punctuation">)</span>
    gin<span class="token punctuation">.</span>DefaultWriter <span class="token operator">=</span> io<span class="token punctuation">.</span><span class="token function">MultiWriter</span><span class="token punctuation">(</span>f<span class="token punctuation">)</span>

    <span class="token comment">// 如果需要将日志同时写入文件和控制台，请使用以下代码</span>
    <span class="token comment">// gin.DefaultWriter = io.MultiWriter(f, os.Stdout)</span>

    router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    router<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/ping"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> <span class="token string">"pong"</span><span class="token punctuation">)</span>
    <span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

    router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">":8080"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<h3 id="自定义日志格式"><a href="#自定义日志格式" class="headerlink" title="自定义日志格式"></a>自定义日志格式</h3><pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	<span class="token comment">// LoggerWithFormatter 中间件会将日志写入 gin.DefaultWriter</span>
	<span class="token comment">// By default gin.DefaultWriter = os.Stdout</span>
	router<span class="token punctuation">.</span><span class="token function">Use</span><span class="token punctuation">(</span>gin<span class="token punctuation">.</span><span class="token function">LoggerWithFormatter</span><span class="token punctuation">(</span><span class="token keyword">func</span><span class="token punctuation">(</span>param gin<span class="token punctuation">.</span>LogFormatterParams<span class="token punctuation">)</span> <span class="token builtin">string</span> <span class="token punctuation">&#123;</span>

		<span class="token comment">// 你的自定义格式</span>
		<span class="token keyword">return</span> fmt<span class="token punctuation">.</span><span class="token function">Sprintf</span><span class="token punctuation">(</span><span class="token string">"%s - [%s] \"%s %s %s %d %s \"%s\" %s\"\n"</span><span class="token punctuation">,</span>
				param<span class="token punctuation">.</span>ClientIP<span class="token punctuation">,</span>
				param<span class="token punctuation">.</span>TimeStamp<span class="token punctuation">.</span><span class="token function">Format</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span>RFC1123<span class="token punctuation">)</span><span class="token punctuation">,</span>
				param<span class="token punctuation">.</span>Method<span class="token punctuation">,</span>
				param<span class="token punctuation">.</span>Path<span class="token punctuation">,</span>
				param<span class="token punctuation">.</span>Request<span class="token punctuation">.</span>Proto<span class="token punctuation">,</span>
				param<span class="token punctuation">.</span>StatusCode<span class="token punctuation">,</span>
				param<span class="token punctuation">.</span>Latency<span class="token punctuation">,</span>
				param<span class="token punctuation">.</span>Request<span class="token punctuation">.</span><span class="token function">UserAgent</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
				param<span class="token punctuation">.</span>ErrorMessage<span class="token punctuation">,</span>
		<span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">Use</span><span class="token punctuation">(</span>gin<span class="token punctuation">.</span><span class="token function">Recovery</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>

	router<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/ping"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> <span class="token string">"pong"</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">":8080"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<p><strong>输出示例：</strong></p>
<pre class="language-none"><code class="language-none">::1 - [Fri, 07 Dec 2018 17:04:38 JST] &quot;GET &#x2F;ping HTTP&#x2F;1.1 200 122.767µs &quot;Mozilla&#x2F;5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit&#x2F;537.36 (KHTML, like Gecko) Chrome&#x2F;71.0.3578.80 Safari&#x2F;537.36&quot; &quot;</code></pre>

<h3 id="模型绑定和验证"><a href="#模型绑定和验证" class="headerlink" title="模型绑定和验证"></a>模型绑定和验证</h3><p>若要将请求主体绑定到结构体中，请使用模型绑定，目前支持JSON、XML、YAML和标准表单值(foo=bar&amp;boo=baz)的绑定。</p>
<p>Gin使用 <a target="_blank" rel="noopener" href="https://github.com/go-playground/validator">go-playground/validator.v8</a> 验证参数，<a target="_blank" rel="noopener" href="https://godoc.org/gopkg.in/go-playground/validator.v8#hdr-Baked_In_Validators_and_Tags">查看完整文档</a>。</p>
<p>需要在绑定的字段上设置tag，比如，绑定格式为json，需要这样设置 <code>json:&quot;fieldname&quot;</code> 。</p>
<p>此外，Gin还提供了两套绑定方法：</p>
<ul>
<li>Must bind</li>
<li><ul>
<li>Methods  - <code>Bind</code>, <code>BindJSON</code>, <code>BindXML</code>, <code>BindQuery</code>, <code>BindYAML</code></li>
</ul>
</li>
<li><ul>
<li>Behavior - 这些方法底层使用 <code>MustBindWith</code>，如果存在绑定错误，请求将被以下指令中止 <code>c.AbortWithError(400, err).SetType(ErrorTypeBind)</code>，响应状态代码会被设置为400，请求头<code>Content-Type</code>被设置为<code>text/plain; charset=utf-8</code>。注意，如果你试图在此之后设置响应代码，将会发出一个警告 <code>[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422</code>，如果你希望更好地控制行为，请使用<code>ShouldBind</code>相关的方法</li>
</ul>
</li>
<li>Should bind</li>
<li><ul>
<li>Methods  - <code>ShouldBind</code>, <code>ShouldBindJSON</code>, <code>ShouldBindXML</code>, <code>ShouldBindQuery</code>, <code>ShouldBindYAML</code></li>
</ul>
</li>
<li><ul>
<li>Behavior - 这些方法底层使用 <code>ShouldBindWith</code>，如果存在绑定错误，则返回错误，开发人员可以正确处理请求和错误。</li>
</ul>
</li>
</ul>
<p>当我们使用绑定方法时，Gin会根据Content-Type推断出使用哪种绑定器，如果你确定你绑定的是什么，你可以使用<code>MustBindWith</code>或者<code>BindingWith</code>。</p>
<p>你还可以给字段指定特定规则的修饰符，如果一个字段用<code>binding:&quot;required&quot;</code>修饰，并且在绑定时该字段的值为空，那么将返回一个错误。</p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token comment">// 绑定为json</span>
<span class="token keyword">type</span> Login <span class="token keyword">struct</span> <span class="token punctuation">&#123;</span>
	User     <span class="token builtin">string</span> <span class="token string">`form:"user" json:"user" xml:"user"  binding:"required"`</span>
	Password <span class="token builtin">string</span> <span class="token string">`form:"password" json:"password" xml:"password" binding:"required"`</span>
<span class="token punctuation">&#125;</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	<span class="token comment">// Example for binding JSON (&#123;"user": "manu", "password": "123"&#125;)</span>
	router<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">"/loginJSON"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		<span class="token keyword">var</span> json Login
		<span class="token keyword">if</span> err <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">ShouldBindJSON</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>json<span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span>
			c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusBadRequest<span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span><span class="token string">"error"</span><span class="token punctuation">:</span> err<span class="token punctuation">.</span><span class="token function">Error</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
			<span class="token keyword">return</span>
		<span class="token punctuation">&#125;</span>

		<span class="token keyword">if</span> json<span class="token punctuation">.</span>User <span class="token operator">!=</span> <span class="token string">"manu"</span> <span class="token operator">||</span> json<span class="token punctuation">.</span>Password <span class="token operator">!=</span> <span class="token string">"123"</span> <span class="token punctuation">&#123;</span>
			c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusUnauthorized<span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span><span class="token string">"status"</span><span class="token punctuation">:</span> <span class="token string">"unauthorized"</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
			<span class="token keyword">return</span>
		<span class="token punctuation">&#125;</span>

		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span><span class="token string">"status"</span><span class="token punctuation">:</span> <span class="token string">"you are logged in"</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

	<span class="token comment">// Example for binding XML (</span>
	<span class="token comment">//	&lt;?xml version="1.0" encoding="UTF-8"?></span>
	<span class="token comment">//	&lt;root></span>
	<span class="token comment">//		&lt;user>user&lt;/user></span>
	<span class="token comment">//		&lt;password>123&lt;/password></span>
	<span class="token comment">//	&lt;/root>)</span>
	router<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">"/loginXML"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		<span class="token keyword">var</span> xml Login
		<span class="token keyword">if</span> err <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">ShouldBindXML</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>xml<span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span>
			c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusBadRequest<span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span><span class="token string">"error"</span><span class="token punctuation">:</span> err<span class="token punctuation">.</span><span class="token function">Error</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
			<span class="token keyword">return</span>
		<span class="token punctuation">&#125;</span>

		<span class="token keyword">if</span> xml<span class="token punctuation">.</span>User <span class="token operator">!=</span> <span class="token string">"manu"</span> <span class="token operator">||</span> xml<span class="token punctuation">.</span>Password <span class="token operator">!=</span> <span class="token string">"123"</span> <span class="token punctuation">&#123;</span>
			c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusUnauthorized<span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span><span class="token string">"status"</span><span class="token punctuation">:</span> <span class="token string">"unauthorized"</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
			<span class="token keyword">return</span>
		<span class="token punctuation">&#125;</span>

		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span><span class="token string">"status"</span><span class="token punctuation">:</span> <span class="token string">"you are logged in"</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

	<span class="token comment">// Example for binding a HTML form (user=manu&amp;password=123)</span>
	router<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">"/loginForm"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		<span class="token keyword">var</span> form Login
		<span class="token comment">// This will infer what binder to use depending on the content-type header.</span>
		<span class="token keyword">if</span> err <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">ShouldBind</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>form<span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span>
			c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusBadRequest<span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span><span class="token string">"error"</span><span class="token punctuation">:</span> err<span class="token punctuation">.</span><span class="token function">Error</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
			<span class="token keyword">return</span>
		<span class="token punctuation">&#125;</span>

		<span class="token keyword">if</span> form<span class="token punctuation">.</span>User <span class="token operator">!=</span> <span class="token string">"manu"</span> <span class="token operator">||</span> form<span class="token punctuation">.</span>Password <span class="token operator">!=</span> <span class="token string">"123"</span> <span class="token punctuation">&#123;</span>
			c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusUnauthorized<span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span><span class="token string">"status"</span><span class="token punctuation">:</span> <span class="token string">"unauthorized"</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
			<span class="token keyword">return</span>
		<span class="token punctuation">&#125;</span>

		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span><span class="token string">"status"</span><span class="token punctuation">:</span> <span class="token string">"you are logged in"</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

	<span class="token comment">// Listen and serve on 0.0.0.0:8080</span>
	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">":8080"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<p><strong>请求示例：</strong></p>
<pre class="language-http" data-language="http"><code class="language-http">$ curl -v -X POST \
  http://localhost:8080/loginJSON \
  -H 'content-type: application/json' \
  -d '&#123; "user": "manu" &#125;'
> POST /loginJSON HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.51.0
> Accept: */*
> content-type: application/json
<span class="token application-json"><span class="token operator">></span> Content<span class="token operator">-</span>Length<span class="token operator">:</span> <span class="token number">18</span>
<span class="token operator">></span>
<span class="token operator">*</span> upload completely sent off<span class="token operator">:</span> <span class="token number">18</span> out <span class="token keyword">of</span> <span class="token number">18</span> bytes
<span class="token operator">&lt;</span> <span class="token constant">HTTP</span><span class="token operator">/</span><span class="token number">1.1</span> <span class="token number">400</span> Bad Request
<span class="token operator">&lt;</span> Content<span class="token operator">-</span>Type<span class="token operator">:</span> application<span class="token operator">/</span>json<span class="token punctuation">;</span> charset<span class="token operator">=</span>utf<span class="token operator">-</span><span class="token number">8</span>
<span class="token operator">&lt;</span> Date<span class="token operator">:</span> Fri<span class="token punctuation">,</span> <span class="token number">04</span> Aug <span class="token number">2017</span> <span class="token number">03</span><span class="token operator">:</span><span class="token number">51</span><span class="token operator">:</span><span class="token number">31</span> <span class="token constant">GMT</span>
<span class="token operator">&lt;</span> Content<span class="token operator">-</span>Length<span class="token operator">:</span> <span class="token number">100</span>
<span class="token operator">&lt;</span>
<span class="token punctuation">&#123;</span><span class="token string-property property">"error"</span><span class="token operator">:</span><span class="token string">"Key: 'Login.Password' Error:Field validation for 'Password' failed on the 'required' tag"</span><span class="token punctuation">&#125;</span></span></code></pre>

<p><strong>跳过验证：</strong></p>
<p>当使用上面的curl命令运行上面的示例时，返回错误，因为示例中<code>Password</code>字段使用了<code>binding:&quot;required&quot;</code>，如果我们使用<code>binding:&quot;-&quot;</code>，那么它就不会报错。</p>
<h3 id="自定义验证器"><a href="#自定义验证器" class="headerlink" title="自定义验证器"></a>自定义验证器</h3><p>Gin允许我们自定义参数验证器，<a target="_blank" rel="noopener" href="https://github.com/gin-gonic/gin/blob/master/examples/custom-validation/server.go">参考1</a>，<a target="_blank" rel="noopener" href="https://github.com/go-playground/validator/releases/tag/v8.7">参考2</a>，<a target="_blank" rel="noopener" href="https://github.com/gin-gonic/gin/tree/master/examples/struct-lvl-validations">参考3</a></p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">package</span> main

<span class="token keyword">import</span> <span class="token punctuation">(</span>
	<span class="token string">"net/http"</span>
	<span class="token string">"reflect"</span>
	<span class="token string">"time"</span>

	<span class="token string">"github.com/gin-gonic/gin"</span>
	<span class="token string">"github.com/gin-gonic/gin/binding"</span>
	<span class="token string">"gopkg.in/go-playground/validator.v8"</span>
<span class="token punctuation">)</span>

<span class="token comment">// Booking contains binded and validated data.</span>
<span class="token keyword">type</span> Booking <span class="token keyword">struct</span> <span class="token punctuation">&#123;</span>
	CheckIn  time<span class="token punctuation">.</span>Time <span class="token string">`form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"`</span>
	CheckOut time<span class="token punctuation">.</span>Time <span class="token string">`form:"check_out" binding:"required,gtfield=CheckIn" time_format:"2006-01-02"`</span>
<span class="token punctuation">&#125;</span>

<span class="token keyword">func</span> <span class="token function">bookableDate</span><span class="token punctuation">(</span>
	v <span class="token operator">*</span>validator<span class="token punctuation">.</span>Validate<span class="token punctuation">,</span> topStruct reflect<span class="token punctuation">.</span>Value<span class="token punctuation">,</span> currentStructOrField reflect<span class="token punctuation">.</span>Value<span class="token punctuation">,</span>
	field reflect<span class="token punctuation">.</span>Value<span class="token punctuation">,</span> fieldType reflect<span class="token punctuation">.</span>Type<span class="token punctuation">,</span> fieldKind reflect<span class="token punctuation">.</span>Kind<span class="token punctuation">,</span> param <span class="token builtin">string</span><span class="token punctuation">,</span>
<span class="token punctuation">)</span> <span class="token builtin">bool</span> <span class="token punctuation">&#123;</span>
	<span class="token keyword">if</span> date<span class="token punctuation">,</span> ok <span class="token operator">:=</span> field<span class="token punctuation">.</span><span class="token function">Interface</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span>Time<span class="token punctuation">)</span><span class="token punctuation">;</span> ok <span class="token punctuation">&#123;</span>
		today <span class="token operator">:=</span> time<span class="token punctuation">.</span><span class="token function">Now</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
		<span class="token keyword">if</span> today<span class="token punctuation">.</span><span class="token function">Year</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">></span> date<span class="token punctuation">.</span><span class="token function">Year</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">||</span> today<span class="token punctuation">.</span><span class="token function">YearDay</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">></span> date<span class="token punctuation">.</span><span class="token function">YearDay</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
			<span class="token keyword">return</span> <span class="token boolean">false</span>
		<span class="token punctuation">&#125;</span>
	<span class="token punctuation">&#125;</span>
	<span class="token keyword">return</span> <span class="token boolean">true</span>
<span class="token punctuation">&#125;</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	route <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	<span class="token keyword">if</span> v<span class="token punctuation">,</span> ok <span class="token operator">:=</span> binding<span class="token punctuation">.</span>Validator<span class="token punctuation">.</span><span class="token function">Engine</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token punctuation">(</span><span class="token operator">*</span>validator<span class="token punctuation">.</span>Validate<span class="token punctuation">)</span><span class="token punctuation">;</span> ok <span class="token punctuation">&#123;</span>
		v<span class="token punctuation">.</span><span class="token function">RegisterValidation</span><span class="token punctuation">(</span><span class="token string">"bookabledate"</span><span class="token punctuation">,</span> bookableDate<span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span>

	route<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/bookable"</span><span class="token punctuation">,</span> getBookable<span class="token punctuation">)</span>
	route<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">":8085"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span>

<span class="token keyword">func</span> <span class="token function">getBookable</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	<span class="token keyword">var</span> b Booking
	<span class="token keyword">if</span> err <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">ShouldBindWith</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>b<span class="token punctuation">,</span> binding<span class="token punctuation">.</span>Query<span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span>
		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span><span class="token string">"message"</span><span class="token punctuation">:</span> <span class="token string">"Booking dates are valid!"</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token punctuation">&#123;</span>
		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusBadRequest<span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span><span class="token string">"error"</span><span class="token punctuation">:</span> err<span class="token punctuation">.</span><span class="token function">Error</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span></code></pre>

<pre class="language-http" data-language="http"><code class="language-http">$ curl "localhost:8085/bookable?check_in=2018-04-16&amp;check_out=2018-04-17"
&#123;"message":"Booking dates are valid!"&#125;

$ curl "localhost:8085/bookable?check_in=2018-03-08&amp;check_out=2018-03-09"
&#123;"error":"Key: 'Booking.CheckIn' Error:Field validation for 'CheckIn' failed on the 'bookabledate' tag"&#125;</code></pre>

<h3 id="只绑定Get参数"><a href="#只绑定Get参数" class="headerlink" title="只绑定Get参数"></a>只绑定Get参数</h3><p><code>ShouldBindQuery</code> 函数只绑定Get参数，不绑定post数据，<a target="_blank" rel="noopener" href="https://github.com/gin-gonic/gin/issues/742#issuecomment-315953017">查看详细信息</a></p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">package</span> main

<span class="token keyword">import</span> <span class="token punctuation">(</span>
	<span class="token string">"log"</span>

	<span class="token string">"github.com/gin-gonic/gin"</span>
<span class="token punctuation">)</span>

<span class="token keyword">type</span> Person <span class="token keyword">struct</span> <span class="token punctuation">&#123;</span>
	Name    <span class="token builtin">string</span> <span class="token string">`form:"name"`</span>
	Address <span class="token builtin">string</span> <span class="token string">`form:"address"`</span>
<span class="token punctuation">&#125;</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	route <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	route<span class="token punctuation">.</span><span class="token function">Any</span><span class="token punctuation">(</span><span class="token string">"/testing"</span><span class="token punctuation">,</span> startPage<span class="token punctuation">)</span>
	route<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">":8085"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span>

<span class="token keyword">func</span> <span class="token function">startPage</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	<span class="token keyword">var</span> person Person
	<span class="token keyword">if</span> c<span class="token punctuation">.</span><span class="token function">ShouldBindQuery</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>person<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span>
		log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"====== Only Bind By Query String ======"</span><span class="token punctuation">)</span>
		log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>person<span class="token punctuation">.</span>Name<span class="token punctuation">)</span>
		log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>person<span class="token punctuation">.</span>Address<span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span>
	c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> <span class="token string">"Success"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<h3 id="绑定Get参数或者Post参数"><a href="#绑定Get参数或者Post参数" class="headerlink" title="绑定Get参数或者Post参数"></a>绑定Get参数或者Post参数</h3><p><a target="_blank" rel="noopener" href="https://github.com/gin-gonic/gin/issues/742#issuecomment-264681292">查看详细信息</a>，这个例子很有用，可以自己实践一下</p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">package</span> main

<span class="token keyword">import</span> <span class="token punctuation">(</span>
	<span class="token string">"log"</span>
	<span class="token string">"time"</span>

	<span class="token string">"github.com/gin-gonic/gin"</span>
<span class="token punctuation">)</span>

<span class="token keyword">type</span> Person <span class="token keyword">struct</span> <span class="token punctuation">&#123;</span>
	Name     <span class="token builtin">string</span>    <span class="token string">`form:"name"`</span>
	Address  <span class="token builtin">string</span>    <span class="token string">`form:"address"`</span>
	Birthday time<span class="token punctuation">.</span>Time <span class="token string">`form:"birthday" time_format:"2006-01-02" time_utc:"1"`</span>
<span class="token punctuation">&#125;</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	route <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	route<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/testing"</span><span class="token punctuation">,</span> startPage<span class="token punctuation">)</span>
	route<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">":8085"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span>

<span class="token keyword">func</span> <span class="token function">startPage</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	<span class="token keyword">var</span> person Person
	<span class="token comment">// If `GET`, only `Form` binding engine (`query`) used.</span>
	<span class="token comment">// 如果是Get，那么接收不到请求中的Post的数据？？</span>
	<span class="token comment">// 如果是Post, 首先判断 `content-type` 的类型 `JSON` or `XML`, 然后使用对应的绑定器获取数据.</span>
	<span class="token comment">// See more at https://github.com/gin-gonic/gin/blob/master/binding/binding.go#L48</span>
	<span class="token keyword">if</span> c<span class="token punctuation">.</span><span class="token function">ShouldBind</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>person<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span>
		log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>person<span class="token punctuation">.</span>Name<span class="token punctuation">)</span>
		log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>person<span class="token punctuation">.</span>Address<span class="token punctuation">)</span>
		log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>person<span class="token punctuation">.</span>Birthday<span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span>

	c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> <span class="token string">"Success"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<h3 id="绑定uri"><a href="#绑定uri" class="headerlink" title="绑定uri"></a>绑定uri</h3><p><a target="_blank" rel="noopener" href="https://github.com/gin-gonic/gin/issues/846">查看详细信息</a></p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">package</span> main

<span class="token keyword">import</span> <span class="token string">"github.com/gin-gonic/gin"</span>

<span class="token keyword">type</span> Person <span class="token keyword">struct</span> <span class="token punctuation">&#123;</span>
	ID <span class="token builtin">string</span> <span class="token string">`uri:"id" binding:"required,uuid"`</span>
	Name <span class="token builtin">string</span> <span class="token string">`uri:"name" binding:"required"`</span>
<span class="token punctuation">&#125;</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	route <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	route<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/:name/:id"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		<span class="token keyword">var</span> person Person
		<span class="token keyword">if</span> err <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">ShouldBindUri</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>person<span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span>
			c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span><span class="token number">400</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span><span class="token string">"msg"</span><span class="token punctuation">:</span> err<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
			<span class="token keyword">return</span>
		<span class="token punctuation">&#125;</span>
		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span><span class="token string">"name"</span><span class="token punctuation">:</span> person<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> <span class="token string">"uuid"</span><span class="token punctuation">:</span> person<span class="token punctuation">.</span>ID<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
	route<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">":8088"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<p>测试用例：</p>
<pre class="language-http" data-language="http"><code class="language-http">$ curl -v localhost:8088/thinkerou/987fbc97-4bed-5078-9f07-9141ba07c9f3
$ curl -v localhost:8088/thinkerou/not-uuid</code></pre>

<h3 id="绑定HTML复选框"><a href="#绑定HTML复选框" class="headerlink" title="绑定HTML复选框"></a>绑定HTML复选框</h3><p><a target="_blank" rel="noopener" href="https://github.com/gin-gonic/gin/issues/129#issuecomment-124260092">查看详细信息</a></p>
<p>main.go</p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token operator">...</span>

<span class="token keyword">type</span> myForm <span class="token keyword">struct</span> <span class="token punctuation">&#123;</span>
    Colors <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span> <span class="token string">`form:"colors[]"`</span>
<span class="token punctuation">&#125;</span>

<span class="token operator">...</span>

<span class="token keyword">func</span> <span class="token function">formHandler</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    <span class="token keyword">var</span> fakeForm myForm
    c<span class="token punctuation">.</span><span class="token function">ShouldBind</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>fakeForm<span class="token punctuation">)</span>
    c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span><span class="token string">"color"</span><span class="token punctuation">:</span> fakeForm<span class="token punctuation">.</span>Colors<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span>

<span class="token operator">...</span></code></pre>

<p>form.html</p>
<pre class="language-markup" data-language="markup"><code class="language-markup"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>form</span> <span class="token attr-name">action</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/<span class="token punctuation">"</span></span> <span class="token attr-name">method</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>POST<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span>Check some colors<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>label</span> <span class="token attr-name">for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>red<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Red<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>label</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>checkbox<span class="token punctuation">"</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>colors[]<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>red<span class="token punctuation">"</span></span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>red<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>label</span> <span class="token attr-name">for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>green<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Green<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>label</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>checkbox<span class="token punctuation">"</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>colors[]<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>green<span class="token punctuation">"</span></span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>green<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>label</span> <span class="token attr-name">for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>blue<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Blue<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>label</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>checkbox<span class="token punctuation">"</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>colors[]<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>blue<span class="token punctuation">"</span></span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>blue<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>submit<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>form</span><span class="token punctuation">></span></span></code></pre>

<p>result:</p>
<pre class="language-json" data-language="json"><code class="language-json"><span class="token punctuation">&#123;</span><span class="token property">"color"</span><span class="token operator">:</span><span class="token punctuation">[</span><span class="token string">"red"</span><span class="token punctuation">,</span><span class="token string">"green"</span><span class="token punctuation">,</span><span class="token string">"blue"</span><span class="token punctuation">]</span><span class="token punctuation">&#125;</span></code></pre>

<h3 id="绑定Post参数"><a href="#绑定Post参数" class="headerlink" title="绑定Post参数"></a>绑定Post参数</h3><pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">package</span> main

<span class="token keyword">import</span> <span class="token punctuation">(</span>
	<span class="token string">"github.com/gin-gonic/gin"</span>
<span class="token punctuation">)</span>

<span class="token keyword">type</span> LoginForm <span class="token keyword">struct</span> <span class="token punctuation">&#123;</span>
	User     <span class="token builtin">string</span> <span class="token string">`form:"user" binding:"required"`</span>
	Password <span class="token builtin">string</span> <span class="token string">`form:"password" binding:"required"`</span>
<span class="token punctuation">&#125;</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">"/login"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		<span class="token comment">// you can bind multipart form with explicit binding declaration:</span>
		<span class="token comment">// c.ShouldBindWith(&amp;form, binding.Form)</span>
		<span class="token comment">// or you can simply use autobinding with ShouldBind method:</span>
		<span class="token keyword">var</span> form LoginForm
		<span class="token comment">// in this case proper binding will be automatically selected</span>
		<span class="token keyword">if</span> c<span class="token punctuation">.</span><span class="token function">ShouldBind</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>form<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span>
			<span class="token keyword">if</span> form<span class="token punctuation">.</span>User <span class="token operator">==</span> <span class="token string">"user"</span> <span class="token operator">&amp;&amp;</span> form<span class="token punctuation">.</span>Password <span class="token operator">==</span> <span class="token string">"password"</span> <span class="token punctuation">&#123;</span>
				c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span><span class="token string">"status"</span><span class="token punctuation">:</span> <span class="token string">"you are logged in"</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
			<span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token punctuation">&#123;</span>
				c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span><span class="token number">401</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span><span class="token string">"status"</span><span class="token punctuation">:</span> <span class="token string">"unauthorized"</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
			<span class="token punctuation">&#125;</span>
		<span class="token punctuation">&#125;</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">":8080"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<p>测试用例：</p>
<pre class="language-http" data-language="http"><code class="language-http">$ curl -v --form user=user --form password=password http://localhost:8080/login</code></pre>

<h3 id="XML、JSON、YAML和ProtoBuf-渲染（输出格式）"><a href="#XML、JSON、YAML和ProtoBuf-渲染（输出格式）" class="headerlink" title="XML、JSON、YAML和ProtoBuf 渲染（输出格式）"></a>XML、JSON、YAML和ProtoBuf 渲染（输出格式）</h3><p>即接口返回的数据格式</p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	<span class="token comment">// gin.H is a shortcut for map[string]interface&#123;&#125;</span>
	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/someJSON"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span><span class="token string">"message"</span><span class="token punctuation">:</span> <span class="token string">"hey"</span><span class="token punctuation">,</span> <span class="token string">"status"</span><span class="token punctuation">:</span> http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/moreJSON"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		<span class="token comment">// You also can use a struct</span>
		<span class="token keyword">var</span> msg <span class="token keyword">struct</span> <span class="token punctuation">&#123;</span>
			Name    <span class="token builtin">string</span> <span class="token string">`json:"user"`</span>
			Message <span class="token builtin">string</span>
			Number  <span class="token builtin">int</span>
		<span class="token punctuation">&#125;</span>
		msg<span class="token punctuation">.</span>Name <span class="token operator">=</span> <span class="token string">"Lena"</span>
		msg<span class="token punctuation">.</span>Message <span class="token operator">=</span> <span class="token string">"hey"</span>
		msg<span class="token punctuation">.</span>Number <span class="token operator">=</span> <span class="token number">123</span>
		<span class="token comment">// Note that msg.Name becomes "user" in the JSON</span>
		<span class="token comment">// Will output  :   &#123;"user": "Lena", "Message": "hey", "Number": 123&#125;</span>
		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> msg<span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/someXML"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		c<span class="token punctuation">.</span><span class="token function">XML</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span><span class="token string">"message"</span><span class="token punctuation">:</span> <span class="token string">"hey"</span><span class="token punctuation">,</span> <span class="token string">"status"</span><span class="token punctuation">:</span> http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/someYAML"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		c<span class="token punctuation">.</span><span class="token function">YAML</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span><span class="token string">"message"</span><span class="token punctuation">:</span> <span class="token string">"hey"</span><span class="token punctuation">,</span> <span class="token string">"status"</span><span class="token punctuation">:</span> http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/someProtoBuf"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		reps <span class="token operator">:=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">int64</span><span class="token punctuation">&#123;</span><span class="token function">int64</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">int64</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">&#125;</span>
		label <span class="token operator">:=</span> <span class="token string">"test"</span>
		<span class="token comment">// The specific definition of protobuf is written in the testdata/protoexample file.</span>
		data <span class="token operator">:=</span> <span class="token operator">&amp;</span>protoexample<span class="token punctuation">.</span>Test<span class="token punctuation">&#123;</span>
			Label<span class="token punctuation">:</span> <span class="token operator">&amp;</span>label<span class="token punctuation">,</span>
			Reps<span class="token punctuation">:</span>  reps<span class="token punctuation">,</span>
		<span class="token punctuation">&#125;</span>
		<span class="token comment">// Note that data becomes binary data in the response</span>
		<span class="token comment">// Will output protoexample.Test protobuf serialized data</span>
		c<span class="token punctuation">.</span><span class="token function">ProtoBuf</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> data<span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

	<span class="token comment">// Listen and serve on 0.0.0.0:8080</span>
	r<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">":8080"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<p><strong>SecureJSON</strong></p>
<p>使用SecureJSON可以防止json劫持，如果返回的数据是数组，则会默认在返回值前加上<code>&quot;while(1)&quot;</code></p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	<span class="token comment">// 可以自定义返回的json数据前缀</span>
	<span class="token comment">// r.SecureJsonPrefix(")]&#125;',\n")</span>

	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/someJSON"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		names <span class="token operator">:=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">&#123;</span><span class="token string">"lena"</span><span class="token punctuation">,</span> <span class="token string">"austin"</span><span class="token punctuation">,</span> <span class="token string">"foo"</span><span class="token punctuation">&#125;</span>

		<span class="token comment">// 将会输出:   while(1);["lena","austin","foo"]</span>
		c<span class="token punctuation">.</span><span class="token function">SecureJSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> names<span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

	<span class="token comment">// Listen and serve on 0.0.0.0:8080</span>
	r<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">":8080"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<p><strong>JSONP</strong></p>
<p>使用JSONP可以跨域传输，如果参数中存在回调参数，那么返回的参数将是回调函数的形式</p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/JSONP"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		data <span class="token operator">:=</span> <span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span><span class="token keyword">interface</span><span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">&#123;</span>
			<span class="token string">"foo"</span><span class="token punctuation">:</span> <span class="token string">"bar"</span><span class="token punctuation">,</span>
		<span class="token punctuation">&#125;</span>

		<span class="token comment">// 访问 http://localhost:8080/JSONP?callback=call</span>
		<span class="token comment">// 将会输出:   call(&#123;foo:"bar"&#125;)</span>
		c<span class="token punctuation">.</span><span class="token function">JSONP</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> data<span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

	<span class="token comment">// Listen and serve on 0.0.0.0:8080</span>
	r<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">":8080"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<p><strong>AsciiJSON</strong></p>
<p>使用AsciiJSON将使特殊字符编码</p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/someJSON"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		data <span class="token operator">:=</span> <span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span><span class="token keyword">interface</span><span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">&#123;</span>
			<span class="token string">"lang"</span><span class="token punctuation">:</span> <span class="token string">"GO语言"</span><span class="token punctuation">,</span>
			<span class="token string">"tag"</span><span class="token punctuation">:</span>  <span class="token string">"&lt;br>"</span><span class="token punctuation">,</span>
		<span class="token punctuation">&#125;</span>

		<span class="token comment">// 将输出: &#123;"lang":"GO\u8bed\u8a00","tag":"\u003cbr\u003e"&#125;</span>
		c<span class="token punctuation">.</span><span class="token function">AsciiJSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> data<span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

	<span class="token comment">// Listen and serve on 0.0.0.0:8080</span>
	r<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">":8080"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<p><strong>PureJSON</strong></p>
<p>通常情况下，JSON会将特殊的HTML字符替换为对应的unicode字符，比如<code>&lt;</code>替换为<code>\u003c</code>，如果想原样输出html，则使用PureJSON，这个特性在Go 1.6及以下版本中无法使用。</p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	<span class="token comment">// Serves unicode entities</span>
	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/json"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span>
			<span class="token string">"html"</span><span class="token punctuation">:</span> <span class="token string">"&lt;b>Hello, world!&lt;/b>"</span><span class="token punctuation">,</span>
		<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

	<span class="token comment">// Serves literal characters</span>
	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/purejson"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		c<span class="token punctuation">.</span><span class="token function">PureJSON</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span>
			<span class="token string">"html"</span><span class="token punctuation">:</span> <span class="token string">"&lt;b>Hello, world!&lt;/b>"</span><span class="token punctuation">,</span>
		<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

	<span class="token comment">// listen and serve on 0.0.0.0:8080</span>
	r<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">":8080"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<h3 id="设置静态文件路径"><a href="#设置静态文件路径" class="headerlink" title="设置静态文件路径"></a>设置静态文件路径</h3><p>访问静态文件需要先设置路径</p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">Static</span><span class="token punctuation">(</span><span class="token string">"/assets"</span><span class="token punctuation">,</span> <span class="token string">"./assets"</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">StaticFS</span><span class="token punctuation">(</span><span class="token string">"/more_static"</span><span class="token punctuation">,</span> http<span class="token punctuation">.</span><span class="token function">Dir</span><span class="token punctuation">(</span><span class="token string">"my_file_system"</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">StaticFile</span><span class="token punctuation">(</span><span class="token string">"/favicon.ico"</span><span class="token punctuation">,</span> <span class="token string">"./resources/favicon.ico"</span><span class="token punctuation">)</span>

	<span class="token comment">// Listen and serve on 0.0.0.0:8080</span>
	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">":8080"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<h3 id="返回第三方获取的数据"><a href="#返回第三方获取的数据" class="headerlink" title="返回第三方获取的数据"></a>返回第三方获取的数据</h3><pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/someDataFromReader"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		response<span class="token punctuation">,</span> err <span class="token operator">:=</span> http<span class="token punctuation">.</span><span class="token function">Get</span><span class="token punctuation">(</span><span class="token string">"https://raw.githubusercontent.com/gin-gonic/logo/master/color.png"</span><span class="token punctuation">)</span>
		<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token operator">||</span> response<span class="token punctuation">.</span>StatusCode <span class="token operator">!=</span> http<span class="token punctuation">.</span>StatusOK <span class="token punctuation">&#123;</span>
			c<span class="token punctuation">.</span><span class="token function">Status</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusServiceUnavailable<span class="token punctuation">)</span>
			<span class="token keyword">return</span>
		<span class="token punctuation">&#125;</span>

		reader <span class="token operator">:=</span> response<span class="token punctuation">.</span>Body
		contentLength <span class="token operator">:=</span> response<span class="token punctuation">.</span>ContentLength
		contentType <span class="token operator">:=</span> response<span class="token punctuation">.</span>Header<span class="token punctuation">.</span><span class="token function">Get</span><span class="token punctuation">(</span><span class="token string">"Content-Type"</span><span class="token punctuation">)</span>

		extraHeaders <span class="token operator">:=</span> <span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">&#123;</span>
			<span class="token string">"Content-Disposition"</span><span class="token punctuation">:</span> <span class="token string">`attachment; filename="gopher.png"`</span><span class="token punctuation">,</span>
		<span class="token punctuation">&#125;</span>

		c<span class="token punctuation">.</span><span class="token function">DataFromReader</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> contentLength<span class="token punctuation">,</span> contentType<span class="token punctuation">,</span> reader<span class="token punctuation">,</span> extraHeaders<span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">":8080"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<h3 id="HTML渲染"><a href="#HTML渲染" class="headerlink" title="HTML渲染"></a>HTML渲染</h3><p>使用<code>LoadHTMLGlob()</code> 或者 <code>LoadHTMLFiles()</code></p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">LoadHTMLGlob</span><span class="token punctuation">(</span><span class="token string">"templates/*"</span><span class="token punctuation">)</span>
	<span class="token comment">//router.LoadHTMLFiles("templates/template1.html", "templates/template2.html")</span>
	router<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/index"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		c<span class="token punctuation">.</span><span class="token function">HTML</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">"index.tmpl"</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span>
			<span class="token string">"title"</span><span class="token punctuation">:</span> <span class="token string">"Main website"</span><span class="token punctuation">,</span>
		<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">":8080"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<p>templates/index.tmpl</p>
<pre class="language-markup" data-language="markup"><code class="language-markup"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span><span class="token punctuation">></span></span>
	<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">></span></span>
		&#123;&#123; .title &#125;&#125;
	<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">></span></span></code></pre>

<p>在不同目录中使用具有相同名称的模板</p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">LoadHTMLGlob</span><span class="token punctuation">(</span><span class="token string">"templates/**/*"</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/posts/index"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		c<span class="token punctuation">.</span><span class="token function">HTML</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">"posts/index.tmpl"</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span>
			<span class="token string">"title"</span><span class="token punctuation">:</span> <span class="token string">"Posts"</span><span class="token punctuation">,</span>
		<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/users/index"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		c<span class="token punctuation">.</span><span class="token function">HTML</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">"users/index.tmpl"</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span>
			<span class="token string">"title"</span><span class="token punctuation">:</span> <span class="token string">"Users"</span><span class="token punctuation">,</span>
		<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">":8080"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<p>templates/posts/index.tmpl</p>
<pre class="language-markup" data-language="markup"><code class="language-markup">&#123;&#123; define "posts/index.tmpl" &#125;&#125;
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">></span></span>
	&#123;&#123; .title &#125;&#125;
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span>Using posts/index.tmpl<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">></span></span>
&#123;&#123; end &#125;&#125;</code></pre>

<p>templates/users/index.tmpl</p>
<pre class="language-markup" data-language="markup"><code class="language-markup">&#123;&#123; define "users/index.tmpl" &#125;&#125;
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">></span></span>
	&#123;&#123; .title &#125;&#125;
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span>Using users/index.tmpl<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">></span></span>
&#123;&#123; end &#125;&#125;</code></pre>

<p><strong>自定义模板渲染器</strong></p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">import</span> <span class="token string">"html/template"</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	html <span class="token operator">:=</span> template<span class="token punctuation">.</span><span class="token function">Must</span><span class="token punctuation">(</span>template<span class="token punctuation">.</span><span class="token function">ParseFiles</span><span class="token punctuation">(</span><span class="token string">"file1"</span><span class="token punctuation">,</span> <span class="token string">"file2"</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">SetHTMLTemplate</span><span class="token punctuation">(</span>html<span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">":8080"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<p><strong>自定义渲染分隔符</strong></p>
<pre class="language-go" data-language="go"><code class="language-go">r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	r<span class="token punctuation">.</span><span class="token function">Delims</span><span class="token punctuation">(</span><span class="token string">"&#123;[&#123;"</span><span class="token punctuation">,</span> <span class="token string">"&#125;]&#125;"</span><span class="token punctuation">)</span>
	r<span class="token punctuation">.</span><span class="token function">LoadHTMLGlob</span><span class="token punctuation">(</span><span class="token string">"/path/to/templates"</span><span class="token punctuation">)</span></code></pre>

<p><strong>自定义模板函数</strong></p>
<p><a target="_blank" rel="noopener" href="https://github.com/gin-gonic/gin/blob/master/examples/template">详细信息</a></p>
<p>main.go</p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">import</span> <span class="token punctuation">(</span>
    <span class="token string">"fmt"</span>
    <span class="token string">"html/template"</span>
    <span class="token string">"net/http"</span>
    <span class="token string">"time"</span>

    <span class="token string">"github.com/gin-gonic/gin"</span>
<span class="token punctuation">)</span>

<span class="token keyword">func</span> <span class="token function">formatAsDate</span><span class="token punctuation">(</span>t time<span class="token punctuation">.</span>Time<span class="token punctuation">)</span> <span class="token builtin">string</span> <span class="token punctuation">&#123;</span>
    year<span class="token punctuation">,</span> month<span class="token punctuation">,</span> day <span class="token operator">:=</span> t<span class="token punctuation">.</span><span class="token function">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token keyword">return</span> fmt<span class="token punctuation">.</span><span class="token function">Sprintf</span><span class="token punctuation">(</span><span class="token string">"%d%02d/%02d"</span><span class="token punctuation">,</span> year<span class="token punctuation">,</span> month<span class="token punctuation">,</span> day<span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    router<span class="token punctuation">.</span><span class="token function">Delims</span><span class="token punctuation">(</span><span class="token string">"&#123;[&#123;"</span><span class="token punctuation">,</span> <span class="token string">"&#125;]&#125;"</span><span class="token punctuation">)</span>
    router<span class="token punctuation">.</span><span class="token function">SetFuncMap</span><span class="token punctuation">(</span>template<span class="token punctuation">.</span>FuncMap<span class="token punctuation">&#123;</span>
        <span class="token string">"formatAsDate"</span><span class="token punctuation">:</span> formatAsDate<span class="token punctuation">,</span>
    <span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
    router<span class="token punctuation">.</span><span class="token function">LoadHTMLFiles</span><span class="token punctuation">(</span><span class="token string">"./testdata/template/raw.tmpl"</span><span class="token punctuation">)</span>

    router<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/raw"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        c<span class="token punctuation">.</span><span class="token function">HTML</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">"raw.tmpl"</span><span class="token punctuation">,</span> <span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span><span class="token keyword">interface</span><span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">&#123;</span>
            <span class="token string">"now"</span><span class="token punctuation">:</span> time<span class="token punctuation">.</span><span class="token function">Date</span><span class="token punctuation">(</span><span class="token number">2017</span><span class="token punctuation">,</span> <span class="token number">07</span><span class="token punctuation">,</span> <span class="token number">01</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> time<span class="token punctuation">.</span>UTC<span class="token punctuation">)</span><span class="token punctuation">,</span>
        <span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
    <span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

    router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">":8080"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<p>raw.tmpl</p>
<p>然后就可以在html中直接使用formatAsDate函数了</p>
<pre class="language-none"><code class="language-none">Date: &#123;[&#123;.now | formatAsDate&#125;]&#125;</code></pre>

<p>Result:</p>
<pre class="language-none"><code class="language-none">Date: 2017&#x2F;07&#x2F;01</code></pre>

<h3 id="多个模板文件"><a href="#多个模板文件" class="headerlink" title="多个模板文件"></a>多个模板文件</h3><p>Gin默认情况下只允许使用一个html模板文件（即一次可以加载多个模板文件），点击<a target="_blank" rel="noopener" href="https://github.com/gin-contrib/multitemplate">这里</a>查看实现案例</p>
<h3 id="重定向"><a href="#重定向" class="headerlink" title="重定向"></a>重定向</h3><p>发布HTTP重定向很容易，支持内部和外部链接</p>
<pre class="language-go" data-language="go"><code class="language-go">r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/test"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	c<span class="token punctuation">.</span><span class="token function">Redirect</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusMovedPermanently<span class="token punctuation">,</span> <span class="token string">"http://www.google.com/"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span></code></pre>

<p>Gin路由重定向，使用如下的<code>HandleContext</code></p>
<pre class="language-go" data-language="go"><code class="language-go">r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/test"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    c<span class="token punctuation">.</span>Request<span class="token punctuation">.</span>URL<span class="token punctuation">.</span>Path <span class="token operator">=</span> <span class="token string">"/test2"</span>
    r<span class="token punctuation">.</span><span class="token function">HandleContext</span><span class="token punctuation">(</span>c<span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/test2"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span><span class="token string">"hello"</span><span class="token punctuation">:</span> <span class="token string">"world"</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span></code></pre>

<h3 id="自定义中间件"><a href="#自定义中间件" class="headerlink" title="自定义中间件"></a>自定义中间件</h3><pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">func</span> <span class="token function">Logger</span><span class="token punctuation">(</span><span class="token punctuation">)</span> gin<span class="token punctuation">.</span>HandlerFunc <span class="token punctuation">&#123;</span>
	<span class="token keyword">return</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		t <span class="token operator">:=</span> time<span class="token punctuation">.</span><span class="token function">Now</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

		<span class="token comment">// Set example variable</span>
		c<span class="token punctuation">.</span><span class="token function">Set</span><span class="token punctuation">(</span><span class="token string">"example"</span><span class="token punctuation">,</span> <span class="token string">"12345"</span><span class="token punctuation">)</span>

		<span class="token comment">// before request</span>

		c<span class="token punctuation">.</span><span class="token function">Next</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

		<span class="token comment">// after request</span>
		latency <span class="token operator">:=</span> time<span class="token punctuation">.</span><span class="token function">Since</span><span class="token punctuation">(</span>t<span class="token punctuation">)</span>
		log<span class="token punctuation">.</span><span class="token function">Print</span><span class="token punctuation">(</span>latency<span class="token punctuation">)</span>

		<span class="token comment">// access the status we are sending</span>
		status <span class="token operator">:=</span> c<span class="token punctuation">.</span>Writer<span class="token punctuation">.</span><span class="token function">Status</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
		log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>status<span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	r<span class="token punctuation">.</span><span class="token function">Use</span><span class="token punctuation">(</span><span class="token function">Logger</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>

	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/test"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		example <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">MustGet</span><span class="token punctuation">(</span><span class="token string">"example"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token punctuation">(</span><span class="token builtin">string</span><span class="token punctuation">)</span>

		<span class="token comment">// it would print: "12345"</span>
		log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>example<span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

	<span class="token comment">// Listen and serve on 0.0.0.0:8080</span>
	r<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">":8080"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<h3 id="使用BasicAuth-（验证）中间件"><a href="#使用BasicAuth-（验证）中间件" class="headerlink" title="使用BasicAuth()（验证）中间件"></a>使用BasicAuth()（验证）中间件</h3><pre class="language-go" data-language="go"><code class="language-go"><span class="token comment">// simulate some private data</span>
<span class="token keyword">var</span> secrets <span class="token operator">=</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span>
	<span class="token string">"foo"</span><span class="token punctuation">:</span>    gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span><span class="token string">"email"</span><span class="token punctuation">:</span> <span class="token string">"foo@bar.com"</span><span class="token punctuation">,</span> <span class="token string">"phone"</span><span class="token punctuation">:</span> <span class="token string">"123433"</span><span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
	<span class="token string">"austin"</span><span class="token punctuation">:</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span><span class="token string">"email"</span><span class="token punctuation">:</span> <span class="token string">"austin@example.com"</span><span class="token punctuation">,</span> <span class="token string">"phone"</span><span class="token punctuation">:</span> <span class="token string">"666"</span><span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
	<span class="token string">"lena"</span><span class="token punctuation">:</span>   gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span><span class="token string">"email"</span><span class="token punctuation">:</span> <span class="token string">"lena@guapa.com"</span><span class="token punctuation">,</span> <span class="token string">"phone"</span><span class="token punctuation">:</span> <span class="token string">"523443"</span><span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token punctuation">&#125;</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	<span class="token comment">// Group using gin.BasicAuth() middleware</span>
	<span class="token comment">// gin.Accounts is a shortcut for map[string]string</span>
	authorized <span class="token operator">:=</span> r<span class="token punctuation">.</span><span class="token function">Group</span><span class="token punctuation">(</span><span class="token string">"/admin"</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span><span class="token function">BasicAuth</span><span class="token punctuation">(</span>gin<span class="token punctuation">.</span>Accounts<span class="token punctuation">&#123;</span>
		<span class="token string">"foo"</span><span class="token punctuation">:</span>    <span class="token string">"bar"</span><span class="token punctuation">,</span>
		<span class="token string">"austin"</span><span class="token punctuation">:</span> <span class="token string">"1234"</span><span class="token punctuation">,</span>
		<span class="token string">"lena"</span><span class="token punctuation">:</span>   <span class="token string">"hello2"</span><span class="token punctuation">,</span>
		<span class="token string">"manu"</span><span class="token punctuation">:</span>   <span class="token string">"4321"</span><span class="token punctuation">,</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">)</span>

	<span class="token comment">// /admin/secrets endpoint</span>
	<span class="token comment">// hit "localhost:8080/admin/secrets</span>
	authorized<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/secrets"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		<span class="token comment">// get user, it was set by the BasicAuth middleware</span>
		user <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">MustGet</span><span class="token punctuation">(</span>gin<span class="token punctuation">.</span>AuthUserKey<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token punctuation">(</span><span class="token builtin">string</span><span class="token punctuation">)</span>
		<span class="token keyword">if</span> secret<span class="token punctuation">,</span> ok <span class="token operator">:=</span> secrets<span class="token punctuation">[</span>user<span class="token punctuation">]</span><span class="token punctuation">;</span> ok <span class="token punctuation">&#123;</span>
			c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span><span class="token string">"user"</span><span class="token punctuation">:</span> user<span class="token punctuation">,</span> <span class="token string">"secret"</span><span class="token punctuation">:</span> secret<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
		<span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token punctuation">&#123;</span>
			c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span><span class="token string">"user"</span><span class="token punctuation">:</span> user<span class="token punctuation">,</span> <span class="token string">"secret"</span><span class="token punctuation">:</span> <span class="token string">"NO SECRET :("</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
		<span class="token punctuation">&#125;</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

	<span class="token comment">// Listen and serve on 0.0.0.0:8080</span>
	r<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">":8080"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<h3 id="中间件中使用Goroutines"><a href="#中间件中使用Goroutines" class="headerlink" title="中间件中使用Goroutines"></a>中间件中使用Goroutines</h3><p>在中间件或处理程序中启动新的Goroutines时，你不应该使用其中的原始上下文，你必须使用只读副本（<code>c.Copy()</code>）</p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/long_async"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		<span class="token comment">// 创建要在goroutine中使用的副本</span>
		cCp <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">Copy</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
		<span class="token keyword">go</span> <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
			<span class="token comment">// simulate a long task with time.Sleep(). 5 seconds</span>
			time<span class="token punctuation">.</span><span class="token function">Sleep</span><span class="token punctuation">(</span><span class="token number">5</span> <span class="token operator">*</span> time<span class="token punctuation">.</span>Second<span class="token punctuation">)</span>

			<span class="token comment">// 这里使用你创建的副本</span>
			log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"Done! in path "</span> <span class="token operator">+</span> cCp<span class="token punctuation">.</span>Request<span class="token punctuation">.</span>URL<span class="token punctuation">.</span>Path<span class="token punctuation">)</span>
		<span class="token punctuation">&#125;</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/long_sync"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		<span class="token comment">// simulate a long task with time.Sleep(). 5 seconds</span>
		time<span class="token punctuation">.</span><span class="token function">Sleep</span><span class="token punctuation">(</span><span class="token number">5</span> <span class="token operator">*</span> time<span class="token punctuation">.</span>Second<span class="token punctuation">)</span>

		<span class="token comment">// 这里没有使用goroutine，所以不用使用副本</span>
		log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"Done! in path "</span> <span class="token operator">+</span> c<span class="token punctuation">.</span>Request<span class="token punctuation">.</span>URL<span class="token punctuation">.</span>Path<span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

	<span class="token comment">// Listen and serve on 0.0.0.0:8080</span>
	r<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">":8080"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<h3 id="自定义HTTP配置"><a href="#自定义HTTP配置" class="headerlink" title="自定义HTTP配置"></a>自定义HTTP配置</h3><p>直接像这样使用<code>http.ListenAndServe()</code></p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	http<span class="token punctuation">.</span><span class="token function">ListenAndServe</span><span class="token punctuation">(</span><span class="token string">":8080"</span><span class="token punctuation">,</span> router<span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<p>或者</p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	s <span class="token operator">:=</span> <span class="token operator">&amp;</span>http<span class="token punctuation">.</span>Server<span class="token punctuation">&#123;</span>
		Addr<span class="token punctuation">:</span>           <span class="token string">":8080"</span><span class="token punctuation">,</span>
		Handler<span class="token punctuation">:</span>        router<span class="token punctuation">,</span>
		ReadTimeout<span class="token punctuation">:</span>    <span class="token number">10</span> <span class="token operator">*</span> time<span class="token punctuation">.</span>Second<span class="token punctuation">,</span>
		WriteTimeout<span class="token punctuation">:</span>   <span class="token number">10</span> <span class="token operator">*</span> time<span class="token punctuation">.</span>Second<span class="token punctuation">,</span>
		MaxHeaderBytes<span class="token punctuation">:</span> <span class="token number">1</span> <span class="token operator">&lt;&lt;</span> <span class="token number">20</span><span class="token punctuation">,</span>
	<span class="token punctuation">&#125;</span>
	s<span class="token punctuation">.</span><span class="token function">ListenAndServe</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<h3 id="支持Let’s-Encrypt证书"><a href="#支持Let’s-Encrypt证书" class="headerlink" title="支持Let’s Encrypt证书"></a>支持Let’s Encrypt证书</h3><p>1行代码实现LetsEncrypt HTTPS服务器</p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">package</span> main

<span class="token keyword">import</span> <span class="token punctuation">(</span>
	<span class="token string">"log"</span>

	<span class="token string">"github.com/gin-gonic/autotls"</span>
	<span class="token string">"github.com/gin-gonic/gin"</span>
<span class="token punctuation">)</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	<span class="token comment">// Ping handler</span>
	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/ping"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> <span class="token string">"pong"</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

	log<span class="token punctuation">.</span><span class="token function">Fatal</span><span class="token punctuation">(</span>autotls<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span>r<span class="token punctuation">,</span> <span class="token string">"example1.com"</span><span class="token punctuation">,</span> <span class="token string">"example2.com"</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<p>自定义autocert管理器的示例</p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">package</span> main

<span class="token keyword">import</span> <span class="token punctuation">(</span>
	<span class="token string">"log"</span>

	<span class="token string">"github.com/gin-gonic/autotls"</span>
	<span class="token string">"github.com/gin-gonic/gin"</span>
	<span class="token string">"golang.org/x/crypto/acme/autocert"</span>
<span class="token punctuation">)</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	<span class="token comment">// Ping handler</span>
	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/ping"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> <span class="token string">"pong"</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

	m <span class="token operator">:=</span> autocert<span class="token punctuation">.</span>Manager<span class="token punctuation">&#123;</span>
		Prompt<span class="token punctuation">:</span>     autocert<span class="token punctuation">.</span>AcceptTOS<span class="token punctuation">,</span>
		HostPolicy<span class="token punctuation">:</span> autocert<span class="token punctuation">.</span><span class="token function">HostWhitelist</span><span class="token punctuation">(</span><span class="token string">"example1.com"</span><span class="token punctuation">,</span> <span class="token string">"example2.com"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
		Cache<span class="token punctuation">:</span>      autocert<span class="token punctuation">.</span><span class="token function">DirCache</span><span class="token punctuation">(</span><span class="token string">"/var/www/.cache"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
	<span class="token punctuation">&#125;</span>

	log<span class="token punctuation">.</span><span class="token function">Fatal</span><span class="token punctuation">(</span>autotls<span class="token punctuation">.</span><span class="token function">RunWithManager</span><span class="token punctuation">(</span>r<span class="token punctuation">,</span> <span class="token operator">&amp;</span>m<span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<h3 id="Gin运行多个服务"><a href="#Gin运行多个服务" class="headerlink" title="Gin运行多个服务"></a>Gin运行多个服务</h3><p>请参阅<a target="_blank" rel="noopener" href="https://github.com/gin-gonic/gin/issues/346">问题</a>并尝试以下示例</p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">package</span> main

<span class="token keyword">import</span> <span class="token punctuation">(</span>
	<span class="token string">"log"</span>
	<span class="token string">"net/http"</span>
	<span class="token string">"time"</span>

	<span class="token string">"github.com/gin-gonic/gin"</span>
	<span class="token string">"golang.org/x/sync/errgroup"</span>
<span class="token punctuation">)</span>

<span class="token keyword">var</span> <span class="token punctuation">(</span>
	g errgroup<span class="token punctuation">.</span>Group
<span class="token punctuation">)</span>

<span class="token keyword">func</span> <span class="token function">router01</span><span class="token punctuation">(</span><span class="token punctuation">)</span> http<span class="token punctuation">.</span>Handler <span class="token punctuation">&#123;</span>
	e <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	e<span class="token punctuation">.</span><span class="token function">Use</span><span class="token punctuation">(</span>gin<span class="token punctuation">.</span><span class="token function">Recovery</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
	e<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>
			http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span>
			gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span>
				<span class="token string">"code"</span><span class="token punctuation">:</span>  http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span>
				<span class="token string">"error"</span><span class="token punctuation">:</span> <span class="token string">"Welcome server 01"</span><span class="token punctuation">,</span>
			<span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
		<span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

	<span class="token keyword">return</span> e
<span class="token punctuation">&#125;</span>

<span class="token keyword">func</span> <span class="token function">router02</span><span class="token punctuation">(</span><span class="token punctuation">)</span> http<span class="token punctuation">.</span>Handler <span class="token punctuation">&#123;</span>
	e <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	e<span class="token punctuation">.</span><span class="token function">Use</span><span class="token punctuation">(</span>gin<span class="token punctuation">.</span><span class="token function">Recovery</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
	e<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>
			http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span>
			gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span>
				<span class="token string">"code"</span><span class="token punctuation">:</span>  http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span>
				<span class="token string">"error"</span><span class="token punctuation">:</span> <span class="token string">"Welcome server 02"</span><span class="token punctuation">,</span>
			<span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
		<span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

	<span class="token keyword">return</span> e
<span class="token punctuation">&#125;</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	server01 <span class="token operator">:=</span> <span class="token operator">&amp;</span>http<span class="token punctuation">.</span>Server<span class="token punctuation">&#123;</span>
		Addr<span class="token punctuation">:</span>         <span class="token string">":8080"</span><span class="token punctuation">,</span>
		Handler<span class="token punctuation">:</span>      <span class="token function">router01</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
		ReadTimeout<span class="token punctuation">:</span>  <span class="token number">5</span> <span class="token operator">*</span> time<span class="token punctuation">.</span>Second<span class="token punctuation">,</span>
		WriteTimeout<span class="token punctuation">:</span> <span class="token number">10</span> <span class="token operator">*</span> time<span class="token punctuation">.</span>Second<span class="token punctuation">,</span>
	<span class="token punctuation">&#125;</span>

	server02 <span class="token operator">:=</span> <span class="token operator">&amp;</span>http<span class="token punctuation">.</span>Server<span class="token punctuation">&#123;</span>
		Addr<span class="token punctuation">:</span>         <span class="token string">":8081"</span><span class="token punctuation">,</span>
		Handler<span class="token punctuation">:</span>      <span class="token function">router02</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
		ReadTimeout<span class="token punctuation">:</span>  <span class="token number">5</span> <span class="token operator">*</span> time<span class="token punctuation">.</span>Second<span class="token punctuation">,</span>
		WriteTimeout<span class="token punctuation">:</span> <span class="token number">10</span> <span class="token operator">*</span> time<span class="token punctuation">.</span>Second<span class="token punctuation">,</span>
	<span class="token punctuation">&#125;</span>

	g<span class="token punctuation">.</span><span class="token function">Go</span><span class="token punctuation">(</span><span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">error</span> <span class="token punctuation">&#123;</span>
		<span class="token keyword">return</span> server01<span class="token punctuation">.</span><span class="token function">ListenAndServe</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

	g<span class="token punctuation">.</span><span class="token function">Go</span><span class="token punctuation">(</span><span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">error</span> <span class="token punctuation">&#123;</span>
		<span class="token keyword">return</span> server02<span class="token punctuation">.</span><span class="token function">ListenAndServe</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

	<span class="token keyword">if</span> err <span class="token operator">:=</span> g<span class="token punctuation">.</span><span class="token function">Wait</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span>
		log<span class="token punctuation">.</span><span class="token function">Fatal</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span></code></pre>

<h3 id="优雅重启或停止"><a href="#优雅重启或停止" class="headerlink" title="优雅重启或停止"></a>优雅重启或停止</h3><p>想要优雅地重启或停止你的Web服务器，使用下面的方法</p>
<p>我们可以使用<a target="_blank" rel="noopener" href="https://github.com/fvbock/endless">fvbock/endless</a>来替换默认的<code>ListenAndServe</code>，有关详细信息，请参阅问题<a target="_blank" rel="noopener" href="https://github.com/gin-gonic/gin/issues/296">＃296</a></p>
<pre class="language-go" data-language="go"><code class="language-go">router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
router<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/"</span><span class="token punctuation">,</span> handler<span class="token punctuation">)</span>
<span class="token comment">// [...]</span>
endless<span class="token punctuation">.</span><span class="token function">ListenAndServe</span><span class="token punctuation">(</span><span class="token string">":4242"</span><span class="token punctuation">,</span> router<span class="token punctuation">)</span></code></pre>

<p>一个替换方案</p>
<ul>
<li><a target="_blank" rel="noopener" href="https://github.com/braintree/manners">manners</a>：一个Go HTTP服务器，能优雅的关闭</li>
<li><a target="_blank" rel="noopener" href="https://github.com/tylerb/graceful">graceful</a>：Graceful是一个go的包，支持优雅地关闭http.Handler服务器</li>
<li><a target="_blank" rel="noopener" href="https://github.com/facebookgo/grace">grace</a>：对Go服务器进行优雅的重启和零停机部署</li>
</ul>
<p>如果你的Go版本是1.8，你可能不需要使用这个库，考虑使用http.Server内置的<a target="_blank" rel="noopener" href="https://golang.org/pkg/net/http/#Server.Shutdown">Shutdown()</a>方法进行优雅关闭，查看<a target="_blank" rel="noopener" href="https://github.com/gin-gonic/gin/tree/master/examples/graceful-shutdown">例子</a></p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token comment">// +build go1.8</span>

<span class="token keyword">package</span> main

<span class="token keyword">import</span> <span class="token punctuation">(</span>
	<span class="token string">"context"</span>
	<span class="token string">"log"</span>
	<span class="token string">"net/http"</span>
	<span class="token string">"os"</span>
	<span class="token string">"os/signal"</span>
	<span class="token string">"time"</span>

	<span class="token string">"github.com/gin-gonic/gin"</span>
<span class="token punctuation">)</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		time<span class="token punctuation">.</span><span class="token function">Sleep</span><span class="token punctuation">(</span><span class="token number">5</span> <span class="token operator">*</span> time<span class="token punctuation">.</span>Second<span class="token punctuation">)</span>
		c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">"Welcome Gin Server"</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

	srv <span class="token operator">:=</span> <span class="token operator">&amp;</span>http<span class="token punctuation">.</span>Server<span class="token punctuation">&#123;</span>
		Addr<span class="token punctuation">:</span>    <span class="token string">":8080"</span><span class="token punctuation">,</span>
		Handler<span class="token punctuation">:</span> router<span class="token punctuation">,</span>
	<span class="token punctuation">&#125;</span>

	<span class="token keyword">go</span> <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		<span class="token comment">// service connections</span>
		<span class="token keyword">if</span> err <span class="token operator">:=</span> srv<span class="token punctuation">.</span><span class="token function">ListenAndServe</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token operator">&amp;&amp;</span> err <span class="token operator">!=</span> http<span class="token punctuation">.</span>ErrServerClosed <span class="token punctuation">&#123;</span>
			log<span class="token punctuation">.</span><span class="token function">Fatalf</span><span class="token punctuation">(</span><span class="token string">"listen: %s\n"</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span>
		<span class="token punctuation">&#125;</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	<span class="token comment">// Wait for interrupt signal to gracefully shutdown the server with</span>
	<span class="token comment">// a timeout of 5 seconds.</span>
	quit <span class="token operator">:=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">chan</span> os<span class="token punctuation">.</span>Signal<span class="token punctuation">)</span>
	signal<span class="token punctuation">.</span><span class="token function">Notify</span><span class="token punctuation">(</span>quit<span class="token punctuation">,</span> os<span class="token punctuation">.</span>Interrupt<span class="token punctuation">)</span>
	<span class="token operator">&lt;-</span>quit
	log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"Shutdown Server ..."</span><span class="token punctuation">)</span>

	ctx<span class="token punctuation">,</span> cancel <span class="token operator">:=</span> context<span class="token punctuation">.</span><span class="token function">WithTimeout</span><span class="token punctuation">(</span>context<span class="token punctuation">.</span><span class="token function">Background</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token operator">*</span>time<span class="token punctuation">.</span>Second<span class="token punctuation">)</span>
	<span class="token keyword">defer</span> <span class="token function">cancel</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	<span class="token keyword">if</span> err <span class="token operator">:=</span> srv<span class="token punctuation">.</span><span class="token function">Shutdown</span><span class="token punctuation">(</span>ctx<span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span>
		log<span class="token punctuation">.</span><span class="token function">Fatal</span><span class="token punctuation">(</span><span class="token string">"Server Shutdown:"</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span>
	log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"Server exiting"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<h3 id="构建包含模板的二进制文件"><a href="#构建包含模板的二进制文件" class="headerlink" title="构建包含模板的二进制文件"></a>构建包含模板的二进制文件</h3><p>你可以使用<a target="_blank" rel="noopener" href="https://github.com/jessevdk/go-assets">go-assets</a>将服务器构建成一个包含模板的二进制文件</p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	t<span class="token punctuation">,</span> err <span class="token operator">:=</span> <span class="token function">loadTemplate</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span>
		<span class="token function">panic</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span>
	r<span class="token punctuation">.</span><span class="token function">SetHTMLTemplate</span><span class="token punctuation">(</span>t<span class="token punctuation">)</span>

	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		c<span class="token punctuation">.</span><span class="token function">HTML</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">"/html/index.tmpl"</span><span class="token punctuation">,</span><span class="token boolean">nil</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
	r<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">":8080"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span>

<span class="token comment">// loadTemplate loads templates embedded by go-assets-builder</span>
<span class="token keyword">func</span> <span class="token function">loadTemplate</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">(</span><span class="token operator">*</span>template<span class="token punctuation">.</span>Template<span class="token punctuation">,</span> <span class="token builtin">error</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	t <span class="token operator">:=</span> template<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span>
	<span class="token keyword">for</span> name<span class="token punctuation">,</span> file <span class="token operator">:=</span> <span class="token keyword">range</span> Assets<span class="token punctuation">.</span>Files <span class="token punctuation">&#123;</span>
		<span class="token keyword">if</span> file<span class="token punctuation">.</span><span class="token function">IsDir</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token operator">!</span>strings<span class="token punctuation">.</span><span class="token function">HasSuffix</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> <span class="token string">".tmpl"</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
			<span class="token keyword">continue</span>
		<span class="token punctuation">&#125;</span>
		h<span class="token punctuation">,</span> err <span class="token operator">:=</span> ioutil<span class="token punctuation">.</span><span class="token function">ReadAll</span><span class="token punctuation">(</span>file<span class="token punctuation">)</span>
		<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span>
			<span class="token keyword">return</span> <span class="token boolean">nil</span><span class="token punctuation">,</span> err
		<span class="token punctuation">&#125;</span>
		t<span class="token punctuation">,</span> err <span class="token operator">=</span> t<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Parse</span><span class="token punctuation">(</span><span class="token function">string</span><span class="token punctuation">(</span>h<span class="token punctuation">)</span><span class="token punctuation">)</span>
		<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span>
			<span class="token keyword">return</span> <span class="token boolean">nil</span><span class="token punctuation">,</span> err
		<span class="token punctuation">&#125;</span>
	<span class="token punctuation">&#125;</span>
	<span class="token keyword">return</span> t<span class="token punctuation">,</span> <span class="token boolean">nil</span>
<span class="token punctuation">&#125;</span></code></pre>

<p>请参见<code>examples/assets-in-binary</code>目录中的例子</p>
<h3 id="使用自定义结构绑定表单数据"><a href="#使用自定义结构绑定表单数据" class="headerlink" title="使用自定义结构绑定表单数据"></a>使用自定义结构绑定表单数据</h3><p>以下示例使用自定义结构</p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">type</span> StructA <span class="token keyword">struct</span> <span class="token punctuation">&#123;</span>
    FieldA <span class="token builtin">string</span> <span class="token string">`form:"field_a"`</span>
<span class="token punctuation">&#125;</span>

<span class="token keyword">type</span> StructB <span class="token keyword">struct</span> <span class="token punctuation">&#123;</span>
    NestedStruct StructA
    FieldB <span class="token builtin">string</span> <span class="token string">`form:"field_b"`</span>
<span class="token punctuation">&#125;</span>

<span class="token keyword">type</span> StructC <span class="token keyword">struct</span> <span class="token punctuation">&#123;</span>
    NestedStructPointer <span class="token operator">*</span>StructA
    FieldC <span class="token builtin">string</span> <span class="token string">`form:"field_c"`</span>
<span class="token punctuation">&#125;</span>

<span class="token keyword">type</span> StructD <span class="token keyword">struct</span> <span class="token punctuation">&#123;</span>
    NestedAnonyStruct <span class="token keyword">struct</span> <span class="token punctuation">&#123;</span>
        FieldX <span class="token builtin">string</span> <span class="token string">`form:"field_x"`</span>
    <span class="token punctuation">&#125;</span>
    FieldD <span class="token builtin">string</span> <span class="token string">`form:"field_d"`</span>
<span class="token punctuation">&#125;</span>

<span class="token keyword">func</span> <span class="token function">GetDataB</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    <span class="token keyword">var</span> b StructB
    c<span class="token punctuation">.</span><span class="token function">Bind</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>b<span class="token punctuation">)</span>
    c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span>
        <span class="token string">"a"</span><span class="token punctuation">:</span> b<span class="token punctuation">.</span>NestedStruct<span class="token punctuation">,</span>
        <span class="token string">"b"</span><span class="token punctuation">:</span> b<span class="token punctuation">.</span>FieldB<span class="token punctuation">,</span>
    <span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span>

<span class="token keyword">func</span> <span class="token function">GetDataC</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    <span class="token keyword">var</span> b StructC
    c<span class="token punctuation">.</span><span class="token function">Bind</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>b<span class="token punctuation">)</span>
    c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span>
        <span class="token string">"a"</span><span class="token punctuation">:</span> b<span class="token punctuation">.</span>NestedStructPointer<span class="token punctuation">,</span>
        <span class="token string">"c"</span><span class="token punctuation">:</span> b<span class="token punctuation">.</span>FieldC<span class="token punctuation">,</span>
    <span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span>

<span class="token keyword">func</span> <span class="token function">GetDataD</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    <span class="token keyword">var</span> b StructD
    c<span class="token punctuation">.</span><span class="token function">Bind</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>b<span class="token punctuation">)</span>
    c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span>
        <span class="token string">"x"</span><span class="token punctuation">:</span> b<span class="token punctuation">.</span>NestedAnonyStruct<span class="token punctuation">,</span>
        <span class="token string">"d"</span><span class="token punctuation">:</span> b<span class="token punctuation">.</span>FieldD<span class="token punctuation">,</span>
    <span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/getb"</span><span class="token punctuation">,</span> GetDataB<span class="token punctuation">)</span>
    r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/getc"</span><span class="token punctuation">,</span> GetDataC<span class="token punctuation">)</span>
    r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/getd"</span><span class="token punctuation">,</span> GetDataD<span class="token punctuation">)</span>

    r<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<p>运行示例：</p>
<pre class="language-http" data-language="http"><code class="language-http">$ curl "http://localhost:8080/getb?field_a=hello&amp;field_b=world"
&#123;"a":&#123;"FieldA":"hello"&#125;,"b":"world"&#125;
$ curl "http://localhost:8080/getc?field_a=hello&amp;field_c=world"
&#123;"a":&#123;"FieldA":"hello"&#125;,"c":"world"&#125;
$ curl "http://localhost:8080/getd?field_x=hello&amp;field_d=world"
&#123;"d":"world","x":&#123;"FieldX":"hello"&#125;&#125;</code></pre>

<p><strong>注意</strong>：不支持以下样式结构</p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">type</span> StructX <span class="token keyword">struct</span> <span class="token punctuation">&#123;</span>
    X <span class="token keyword">struct</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span> <span class="token string">`form:"name_x"`</span> <span class="token comment">// HERE have form</span>
<span class="token punctuation">&#125;</span>

<span class="token keyword">type</span> StructY <span class="token keyword">struct</span> <span class="token punctuation">&#123;</span>
    Y StructX <span class="token string">`form:"name_y"`</span> <span class="token comment">// HERE have form</span>
<span class="token punctuation">&#125;</span>

<span class="token keyword">type</span> StructZ <span class="token keyword">struct</span> <span class="token punctuation">&#123;</span>
    Z <span class="token operator">*</span>StructZ <span class="token string">`form:"name_z"`</span> <span class="token comment">// HERE have form</span>
<span class="token punctuation">&#125;</span></code></pre>

<p>总之，现在只支持现在没有<code>form</code>标签的自定义结构</p>
<h3 id="将请求体绑定到不同的结构体中"><a href="#将请求体绑定到不同的结构体中" class="headerlink" title="将请求体绑定到不同的结构体中"></a>将请求体绑定到不同的结构体中</h3><p>绑定请求体的常规方法使用<code>c.Request.Body</code>，并且不能多次调用</p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">type</span> formA <span class="token keyword">struct</span> <span class="token punctuation">&#123;</span>
  Foo <span class="token builtin">string</span> <span class="token string">`json:"foo" xml:"foo" binding:"required"`</span>
<span class="token punctuation">&#125;</span>

<span class="token keyword">type</span> formB <span class="token keyword">struct</span> <span class="token punctuation">&#123;</span>
  Bar <span class="token builtin">string</span> <span class="token string">`json:"bar" xml:"bar" binding:"required"`</span>
<span class="token punctuation">&#125;</span>

<span class="token keyword">func</span> <span class="token function">SomeHandler</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
  objA <span class="token operator">:=</span> formA<span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span>
  objB <span class="token operator">:=</span> formB<span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span>
  <span class="token comment">// This c.ShouldBind consumes c.Request.Body and it cannot be reused.</span>
  <span class="token keyword">if</span> errA <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">ShouldBind</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>objA<span class="token punctuation">)</span><span class="token punctuation">;</span> errA <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span>
    c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">`the body should be formA`</span><span class="token punctuation">)</span>
  <span class="token comment">// Always an error is occurred by this because c.Request.Body is EOF now.</span>
  <span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token keyword">if</span> errB <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">ShouldBind</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>objB<span class="token punctuation">)</span><span class="token punctuation">;</span> errB <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span>
    c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">`the body should be formB`</span><span class="token punctuation">)</span>
  <span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token punctuation">&#123;</span>
    <span class="token operator">...</span>
  <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span></code></pre>

<p>同样，你能使用<code>c.ShouldBindBodyWith</code></p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">func</span> <span class="token function">SomeHandler</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
  objA <span class="token operator">:=</span> formA<span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span>
  objB <span class="token operator">:=</span> formB<span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span>
  <span class="token comment">// This reads c.Request.Body and stores the result into the context.</span>
  <span class="token keyword">if</span> errA <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">ShouldBindBodyWith</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>objA<span class="token punctuation">,</span> binding<span class="token punctuation">.</span>JSON<span class="token punctuation">)</span><span class="token punctuation">;</span> errA <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span>
    c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">`the body should be formA`</span><span class="token punctuation">)</span>
  <span class="token comment">// At this time, it reuses body stored in the context.</span>
  <span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token keyword">if</span> errB <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">ShouldBindBodyWith</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>objB<span class="token punctuation">,</span> binding<span class="token punctuation">.</span>JSON<span class="token punctuation">)</span><span class="token punctuation">;</span> errB <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span>
    c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">`the body should be formB JSON`</span><span class="token punctuation">)</span>
  <span class="token comment">// And it can accepts other formats</span>
  <span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token keyword">if</span> errB2 <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">ShouldBindBodyWith</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>objB<span class="token punctuation">,</span> binding<span class="token punctuation">.</span>XML<span class="token punctuation">)</span><span class="token punctuation">;</span> errB2 <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span>
    c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">`the body should be formB XML`</span><span class="token punctuation">)</span>
  <span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token punctuation">&#123;</span>
    <span class="token operator">...</span>
  <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span></code></pre>

<ul>
<li><code>c.ShouldBindBodyWith</code> 在绑定之前将body存储到上下文中，这对性能有轻微影响，因此如果你要立即调用，则不应使用此方法</li>
<li>此功能仅适用于这些格式 – <code>JSON</code>, <code>XML</code>, <code>MsgPack</code>, <code>ProtoBuf</code>。对于其他格式，<code>Query</code>, <code>Form</code>, <code>FormPost</code>, <code>FormMultipart</code>, 可以被<code>c.ShouldBind()</code>多次调用而不影响性能（参考 <a target="_blank" rel="noopener" href="https://github.com/gin-gonic/gin/pull/1341">#1341</a>）</li>
</ul>
<h3 id="HTTP-2-服务器推送"><a href="#HTTP-2-服务器推送" class="headerlink" title="HTTP/2 服务器推送"></a>HTTP/2 服务器推送</h3><p><code>http.Pusher</code>只支持Go 1.8或更高版本，有关详细信息，请参阅<a target="_blank" rel="noopener" href="https://blog.golang.org/h2push">golang博客</a></p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">package</span> main

<span class="token keyword">import</span> <span class="token punctuation">(</span>
	<span class="token string">"html/template"</span>
	<span class="token string">"log"</span>

	<span class="token string">"github.com/gin-gonic/gin"</span>
<span class="token punctuation">)</span>

<span class="token keyword">var</span> html <span class="token operator">=</span> template<span class="token punctuation">.</span><span class="token function">Must</span><span class="token punctuation">(</span>template<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span><span class="token string">"https"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Parse</span><span class="token punctuation">(</span><span class="token string">`
&lt;html>
&lt;head>
  &lt;title>Https Test&lt;/title>
  &lt;script src="/assets/app.js">&lt;/script>
&lt;/head>
&lt;body>
  &lt;h1 style="color:red;">Welcome, Ginner!&lt;/h1>
&lt;/body>
&lt;/html>
`</span><span class="token punctuation">)</span><span class="token punctuation">)</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	r<span class="token punctuation">.</span><span class="token function">Static</span><span class="token punctuation">(</span><span class="token string">"/assets"</span><span class="token punctuation">,</span> <span class="token string">"./assets"</span><span class="token punctuation">)</span>
	r<span class="token punctuation">.</span><span class="token function">SetHTMLTemplate</span><span class="token punctuation">(</span>html<span class="token punctuation">)</span>

	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		<span class="token keyword">if</span> pusher <span class="token operator">:=</span> c<span class="token punctuation">.</span>Writer<span class="token punctuation">.</span><span class="token function">Pusher</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> pusher <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span>
			<span class="token comment">// use pusher.Push() to do server push</span>
			<span class="token keyword">if</span> err <span class="token operator">:=</span> pusher<span class="token punctuation">.</span><span class="token function">Push</span><span class="token punctuation">(</span><span class="token string">"/assets/app.js"</span><span class="token punctuation">,</span> <span class="token boolean">nil</span><span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span>
				log<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"Failed to push: %v"</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span>
			<span class="token punctuation">&#125;</span>
		<span class="token punctuation">&#125;</span>
		c<span class="token punctuation">.</span><span class="token function">HTML</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> <span class="token string">"https"</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">&#123;</span>
			<span class="token string">"status"</span><span class="token punctuation">:</span> <span class="token string">"success"</span><span class="token punctuation">,</span>
		<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

	<span class="token comment">// Listen and Server in https://127.0.0.1:8080</span>
	r<span class="token punctuation">.</span><span class="token function">RunTLS</span><span class="token punctuation">(</span><span class="token string">":8080"</span><span class="token punctuation">,</span> <span class="token string">"./testdata/server.pem"</span><span class="token punctuation">,</span> <span class="token string">"./testdata/server.key"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<h3 id="自定义路由日志的格式"><a href="#自定义路由日志的格式" class="headerlink" title="自定义路由日志的格式"></a>自定义路由日志的格式</h3><p>默认的路由日志是这样的：</p>
<pre class="language-log" data-language="log"><code class="language-log"><span class="token punctuation">[</span>GIN<span class="token operator">-</span>debug<span class="token punctuation">]</span> POST   <span class="token file-path string">/foo</span>                      <span class="token operator">-</span><span class="token operator">-</span><span class="token operator">></span> <span class="token domain constant">main.main.func1</span> <span class="token operator">(</span><span class="token number">3</span> handlers<span class="token operator">)</span>
<span class="token punctuation">[</span>GIN<span class="token operator">-</span>debug<span class="token punctuation">]</span> GET    <span class="token file-path string">/bar</span>                      <span class="token operator">-</span><span class="token operator">-</span><span class="token operator">></span> <span class="token domain constant">main.main.func2</span> <span class="token operator">(</span><span class="token number">3</span> handlers<span class="token operator">)</span>
<span class="token punctuation">[</span>GIN<span class="token operator">-</span>debug<span class="token punctuation">]</span> GET    <span class="token file-path string">/status</span>                   <span class="token operator">-</span><span class="token operator">-</span><span class="token operator">></span> <span class="token domain constant">main.main.func3</span> <span class="token operator">(</span><span class="token number">3</span> handlers<span class="token operator">)</span></code></pre>

<p>如果你想以给定的格式记录这些信息（例如 JSON，键值对或其他格式），你可以使用<code>gin.DebugPrintRouteFunc</code>来定义格式，在下面的示例中，我们使用标准日志包记录路由日志，你可以使用其他适合你需求的日志工具</p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">import</span> <span class="token punctuation">(</span>
	<span class="token string">"log"</span>
	<span class="token string">"net/http"</span>

	<span class="token string">"github.com/gin-gonic/gin"</span>
<span class="token punctuation">)</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	gin<span class="token punctuation">.</span>DebugPrintRouteFunc <span class="token operator">=</span> <span class="token keyword">func</span><span class="token punctuation">(</span>httpMethod<span class="token punctuation">,</span> absolutePath<span class="token punctuation">,</span> handlerName <span class="token builtin">string</span><span class="token punctuation">,</span> nuHandlers <span class="token builtin">int</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		log<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"endpoint %v %v %v %v\n"</span><span class="token punctuation">,</span> httpMethod<span class="token punctuation">,</span> absolutePath<span class="token punctuation">,</span> handlerName<span class="token punctuation">,</span> nuHandlers<span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span>

	r<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">"/foo"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">"foo"</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/bar"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">"bar"</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/status"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">"ok"</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

	<span class="token comment">// Listen and Server in http://0.0.0.0:8080</span>
	r<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<h3 id="设置并获取cookie"><a href="#设置并获取cookie" class="headerlink" title="设置并获取cookie"></a>设置并获取cookie</h3><pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">import</span> <span class="token punctuation">(</span>
    <span class="token string">"fmt"</span>

    <span class="token string">"github.com/gin-gonic/gin"</span>
<span class="token punctuation">)</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>

    router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

    router<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/cookie"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>

        cookie<span class="token punctuation">,</span> err <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">Cookie</span><span class="token punctuation">(</span><span class="token string">"gin_cookie"</span><span class="token punctuation">)</span>

        <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span>
            cookie <span class="token operator">=</span> <span class="token string">"NotSet"</span>
            c<span class="token punctuation">.</span><span class="token function">SetCookie</span><span class="token punctuation">(</span><span class="token string">"gin_cookie"</span><span class="token punctuation">,</span> <span class="token string">"test"</span><span class="token punctuation">,</span> <span class="token number">3600</span><span class="token punctuation">,</span> <span class="token string">"/"</span><span class="token punctuation">,</span> <span class="token string">"localhost"</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span>
        <span class="token punctuation">&#125;</span>

        fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"Cookie value: %s \n"</span><span class="token punctuation">,</span> cookie<span class="token punctuation">)</span>
    <span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

    router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<h3 id="测试"><a href="#测试" class="headerlink" title="测试"></a>测试</h3><p><code>net/http/httptest</code>包是http测试的首选方式</p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">package</span> main

<span class="token keyword">func</span> <span class="token function">setupRouter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">*</span>gin<span class="token punctuation">.</span>Engine <span class="token punctuation">&#123;</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">"/ping"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> <span class="token string">"pong"</span><span class="token punctuation">)</span>
	<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
	<span class="token keyword">return</span> r
<span class="token punctuation">&#125;</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	r <span class="token operator">:=</span> <span class="token function">setupRouter</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	r<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">":8080"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<p>测试上面的示例代码</p>
<pre class="language-go" data-language="go"><code class="language-go"><span class="token keyword">package</span> main

<span class="token keyword">import</span> <span class="token punctuation">(</span>
	<span class="token string">"net/http"</span>
	<span class="token string">"net/http/httptest"</span>
	<span class="token string">"testing"</span>

	<span class="token string">"github.com/stretchr/testify/assert"</span>
<span class="token punctuation">)</span>

<span class="token keyword">func</span> <span class="token function">TestPingRoute</span><span class="token punctuation">(</span>t <span class="token operator">*</span>testing<span class="token punctuation">.</span>T<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
	router <span class="token operator">:=</span> <span class="token function">setupRouter</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	w <span class="token operator">:=</span> httptest<span class="token punctuation">.</span><span class="token function">NewRecorder</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	req<span class="token punctuation">,</span> <span class="token boolean">_</span> <span class="token operator">:=</span> http<span class="token punctuation">.</span><span class="token function">NewRequest</span><span class="token punctuation">(</span><span class="token string">"GET"</span><span class="token punctuation">,</span> <span class="token string">"/ping"</span><span class="token punctuation">,</span> <span class="token boolean">nil</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">ServeHTTP</span><span class="token punctuation">(</span>w<span class="token punctuation">,</span> req<span class="token punctuation">)</span>

	assert<span class="token punctuation">.</span><span class="token function">Equal</span><span class="token punctuation">(</span>t<span class="token punctuation">,</span> <span class="token number">200</span><span class="token punctuation">,</span> w<span class="token punctuation">.</span>Code<span class="token punctuation">)</span>
	assert<span class="token punctuation">.</span><span class="token function">Equal</span><span class="token punctuation">(</span>t<span class="token punctuation">,</span> <span class="token string">"pong"</span><span class="token punctuation">,</span> w<span class="token punctuation">.</span>Body<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre>

<h2 id="用户"><a href="#用户" class="headerlink" title="用户"></a>用户</h2><p>以下是使用Gin的一些用户</p>
<ul>
<li><a target="_blank" rel="noopener" href="https://github.com/drone/drone">drone</a>: Drone is a Continuous Delivery platform built on Docker, written in Go.</li>
<li><a target="_blank" rel="noopener" href="https://github.com/appleboy/gorush">gorush</a>: A push notification server written in Go.</li>
<li><a target="_blank" rel="noopener" href="https://github.com/fnproject/fn">fnproject</a>: The container native, cloud agnostic serverless platform.</li>
<li><a target="_blank" rel="noopener" href="https://github.com/photoprism/photoprism">photoprism</a>: Personal photo management powered by Go and Google TensorFlow.</li>
<li><a target="_blank" rel="noopener" href="https://github.com/devopsfaith/krakend">krakend</a>: Ultra performant API Gateway with middlewares.</li>
<li><a target="_blank" rel="noopener" href="https://github.com/thoas/picfit">picfit</a>: An image resizing server written in Go.</li>
</ul>

                
            </div>
            <hr/>

            

    <div class="reprint" id="reprint-statement">
        
            <div class="reprint__author">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-user">
                        文章作者:
                    </i>
                </span>
                <span class="reprint-info">
                    <a href="/about" rel="external nofollow noreferrer">JIANG XIAOFAN</a>
                </span>
            </div>
            <div class="reprint__type">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-link">
                        文章链接:
                    </i>
                </span>
                <span class="reprint-info">
                    <a href="https://shuangdeyu.gitee.io/2018/06/08/gin-kuang-jia-zhong-wen-wen-dang/">https://shuangdeyu.gitee.io/2018/06/08/gin-kuang-jia-zhong-wen-wen-dang/</a>
                </span>
            </div>
            <div class="reprint__notice">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-copyright">
                        版权声明:
                    </i>
                </span>
                <span class="reprint-info">
                    本博客所有文章除特別声明外，均采用
                    <a href="https://creativecommons.org/licenses/by/4.0/deed.zh" rel="external nofollow noreferrer" target="_blank">CC BY 4.0</a>
                    许可协议。转载请注明来源
                    <a href="/about" target="_blank">JIANG XIAOFAN</a>
                    !
                </span>
            </div>
        
    </div>

    <script async defer>
      document.addEventListener("copy", function (e) {
        let toastHTML = '<span>复制成功，请遵循本文的转载规则</span><button class="btn-flat toast-action" onclick="navToReprintStatement()" style="font-size: smaller">查看</a>';
        M.toast({html: toastHTML})
      });

      function navToReprintStatement() {
        $("html, body").animate({scrollTop: $("#reprint-statement").offset().top - 80}, 800);
      }
    </script>



            <div class="tag_share" style="display: block;">
                <div class="post-meta__tag-list" style="display: inline-block;">
                    
                        <div class="article-tag">
                            
                                <a href="/tags/Go/">
                                    <span class="chip bg-color">Go</span>
                                </a>
                            
                                <a href="/tags/Gin/">
                                    <span class="chip bg-color">Gin</span>
                                </a>
                            
                        </div>
                    
                </div>
                <div class="post_share" style="zoom: 80%; width: fit-content; display: inline-block; float: right; margin: -0.15rem 0;">
                    <link rel="stylesheet" type="text/css" href="/libs/share/css/share.min.css">
<div id="article-share">

    
    <div class="social-share" data-sites="twitter,facebook,google,qq,qzone,wechat,weibo,douban,linkedin" data-wechat-qrcode-helper="<p>微信扫一扫即可分享！</p>"></div>
    <script src="/libs/share/js/social-share.min.js"></script>
    

    

</div>

                </div>
            </div>
            
        </div>
    </div>

    

    

    

    

    
        <style>
    .valine-card {
        margin: 1.5rem auto;
    }

    .valine-card .card-content {
        padding: 20px 20px 5px 20px;
    }

    #vcomments textarea {
        box-sizing: border-box;
        background: url("/medias/comment_bg4.jpeg") 100% 100% no-repeat;
    }

    #vcomments p {
        margin: 2px 2px 10px;
        font-size: 1.05rem;
        line-height: 1.78rem;
    }

    #vcomments blockquote p {
        text-indent: 0.2rem;
    }

    #vcomments a {
        padding: 0 2px;
        color: #4cbf30;
        font-weight: 500;
        text-decoration: none;
    }

    #vcomments img {
        max-width: 100%;
        height: auto;
        cursor: pointer;
    }

    #vcomments ol li {
        list-style-type: decimal;
    }

    #vcomments ol,
    ul {
        display: block;
        padding-left: 2em;
        word-spacing: 0.05rem;
    }

    #vcomments ul li,
    ol li {
        display: list-item;
        line-height: 1.8rem;
        font-size: 1rem;
    }

    #vcomments ul li {
        list-style-type: disc;
    }

    #vcomments ul ul li {
        list-style-type: circle;
    }

    #vcomments table, th, td {
        padding: 12px 13px;
        border: 1px solid #dfe2e5;
    }

    #vcomments table, th, td {
        border: 0;
    }

    table tr:nth-child(2n), thead {
        background-color: #fafafa;
    }

    #vcomments table th {
        background-color: #f2f2f2;
        min-width: 80px;
    }

    #vcomments table td {
        min-width: 80px;
    }

    #vcomments h1 {
        font-size: 1.85rem;
        font-weight: bold;
        line-height: 2.2rem;
    }

    #vcomments h2 {
        font-size: 1.65rem;
        font-weight: bold;
        line-height: 1.9rem;
    }

    #vcomments h3 {
        font-size: 1.45rem;
        font-weight: bold;
        line-height: 1.7rem;
    }

    #vcomments h4 {
        font-size: 1.25rem;
        font-weight: bold;
        line-height: 1.5rem;
    }

    #vcomments h5 {
        font-size: 1.1rem;
        font-weight: bold;
        line-height: 1.4rem;
    }

    #vcomments h6 {
        font-size: 1rem;
        line-height: 1.3rem;
    }

    #vcomments p {
        font-size: 1rem;
        line-height: 1.5rem;
    }

    #vcomments hr {
        margin: 12px 0;
        border: 0;
        border-top: 1px solid #ccc;
    }

    #vcomments blockquote {
        margin: 15px 0;
        border-left: 5px solid #42b983;
        padding: 1rem 0.8rem 0.3rem 0.8rem;
        color: #666;
        background-color: rgba(66, 185, 131, .1);
    }

    #vcomments pre {
        font-family: monospace, monospace;
        padding: 1.2em;
        margin: .5em 0;
        background: #272822;
        overflow: auto;
        border-radius: 0.3em;
        tab-size: 4;
    }

    #vcomments code {
        font-family: monospace, monospace;
        padding: 1px 3px;
        font-size: 0.92rem;
        color: #e96900;
        background-color: #f8f8f8;
        border-radius: 2px;
    }

    #vcomments pre code {
        font-family: monospace, monospace;
        padding: 0;
        color: #e8eaf6;
        background-color: #272822;
    }

    #vcomments pre[class*="language-"] {
        padding: 1.2em;
        margin: .5em 0;
    }

    #vcomments code[class*="language-"],
    pre[class*="language-"] {
        color: #e8eaf6;
    }

    #vcomments [type="checkbox"]:not(:checked), [type="checkbox"]:checked {
        position: inherit;
        margin-left: -1.3rem;
        margin-right: 0.4rem;
        margin-top: -1px;
        vertical-align: middle;
        left: unset;
        visibility: visible;
    }

    #vcomments b,
    strong {
        font-weight: bold;
    }

    #vcomments dfn {
        font-style: italic;
    }

    #vcomments small {
        font-size: 85%;
    }

    #vcomments cite {
        font-style: normal;
    }

    #vcomments mark {
        background-color: #fcf8e3;
        padding: .2em;
    }

    #vcomments table, th, td {
        padding: 12px 13px;
        border: 1px solid #dfe2e5;
    }

    table tr:nth-child(2n), thead {
        background-color: #fafafa;
    }

    #vcomments table th {
        background-color: #f2f2f2;
        min-width: 80px;
    }

    #vcomments table td {
        min-width: 80px;
    }

    #vcomments [type="checkbox"]:not(:checked), [type="checkbox"]:checked {
        position: inherit;
        margin-left: -1.3rem;
        margin-right: 0.4rem;
        margin-top: -1px;
        vertical-align: middle;
        left: unset;
        visibility: visible;
    }
</style>

<div class="card valine-card" data-aos="fade-up">
    <div class="comment_headling" style="font-size: 20px; font-weight: 700; position: relative; padding-left: 20px; top: 15px; padding-bottom: 5px;">
        <i class="fas fa-comments fa-fw" aria-hidden="true"></i>
        <span>评论</span>
    </div>
    <div id="vcomments" class="card-content" style="display: grid">
    </div>
</div>

<script src="/libs/valine/av-min.js"></script>
<script src="/libs/valine/Valine.min.js"></script>
<script>
    new Valine({
        el: '#vcomments',
        appId: 'Cu0yGDQXYEoC2BMFqoMyqSK1-gzGzoHsz',
        appKey: 'PYfyCYN5lI59X5Rczd5IGls5',
        notify: 'false' === 'true',
        verify: 'true' === 'true',
        visitor: 'true' === 'true',
        avatar: 'mm',
        pageSize: '20',
        lang: 'zh-cn',
        placeholder: 'hi，留个脚印吧'
    });
</script>

    

    

    

    

<article id="prenext-posts" class="prev-next articles">
    <div class="row article-row">
        
        <div class="article col s12 m6" data-aos="fade-up">
            <div class="article-badge left-badge text-color">
                <i class="fas fa-chevron-left"></i>&nbsp;上一篇</div>
            <div class="card">
                <a href="/2018/09/05/wo-shi-cong-shi-me-shi-hou-kai-shi-bian-zhai-de/">
                    <div class="card-image">
                        
                        <img src="/gallery/bianzhai.jpg" class="responsive-img" alt="我是从什么时候开始变宅的">
                        
                        <span class="card-title">我是从什么时候开始变宅的</span>
                    </div>
                </a>
                <div class="card-content article-content">
                    <div class="summary block-with-text">
                        
                            
                        
                    </div>
                    <div class="publish-info">
                        <span class="publish-date">
                            <i class="far fa-clock fa-fw icon-date"></i>2018-09-05
                        </span>
                        <span class="publish-author">
                            
                            <i class="fas fa-bookmark fa-fw icon-category"></i>
                            
                            <a href="/categories/%E9%97%B2%E8%B0%88/" class="post-category">
                                    闲谈
                                </a>
                            
                            
                        </span>
                    </div>
                </div>
                
                <div class="card-action article-tags">
                    
                    <a href="/tags/%E7%94%9F%E6%B4%BB/">
                        <span class="chip bg-color">生活</span>
                    </a>
                    
                </div>
                
            </div>
        </div>
        
        
        <div class="article col s12 m6" data-aos="fade-up">
            <div class="article-badge right-badge text-color">
                下一篇&nbsp;<i class="fas fa-chevron-right"></i>
            </div>
            <div class="card">
                <a href="/2018/04/25/gitlab-an-zhuang-jiao-cheng/">
                    <div class="card-image">
                        
                        <img src="/gallery/gitlab.jpg" class="responsive-img" alt="gitlab安装教程">
                        
                        <span class="card-title">gitlab安装教程</span>
                    </div>
                </a>
                <div class="card-content article-content">
                    <div class="summary block-with-text">
                        
                            
                        
                    </div>
                    <div class="publish-info">
                            <span class="publish-date">
                                <i class="far fa-clock fa-fw icon-date"></i>2018-04-25
                            </span>
                        <span class="publish-author">
                            
                            <i class="fas fa-bookmark fa-fw icon-category"></i>
                            
                            <a href="/categories/%E6%8A%80%E6%9C%AF/" class="post-category">
                                    技术
                                </a>
                            
                            
                        </span>
                    </div>
                </div>
                
                <div class="card-action article-tags">
                    
                    <a href="/tags/gitlab/">
                        <span class="chip bg-color">gitlab</span>
                    </a>
                    
                </div>
                
            </div>
        </div>
        
    </div>
</article>

</div>



<!-- 代码块功能依赖 -->
<script type="text/javascript" src="/libs/codeBlock/codeBlockFuction.js"></script>

<!-- 代码语言 -->

<script type="text/javascript" src="/libs/codeBlock/codeLang.js"></script>


<!-- 代码块复制 -->

<script type="text/javascript" src="/libs/codeBlock/codeCopy.js"></script>


<!-- 代码块收缩 -->

<script type="text/javascript" src="/libs/codeBlock/codeShrink.js"></script>


    </div>
    <div id="toc-aside" class="expanded col l3 hide-on-med-and-down">
        <div class="toc-widget card" style="background-color: white;">
            <div class="toc-title"><i class="far fa-list-alt"></i>&nbsp;&nbsp;目录</div>
            <div id="toc-content"></div>
        </div>
    </div>
</div>

<!-- TOC 悬浮按钮. -->

<div id="floating-toc-btn" class="hide-on-med-and-down">
    <a class="btn-floating btn-large bg-color">
        <i class="fas fa-list-ul"></i>
    </a>
</div>


<script src="/libs/tocbot/tocbot.min.js"></script>
<script>
    $(function () {
        tocbot.init({
            tocSelector: '#toc-content',
            contentSelector: '#articleContent',
            headingsOffset: -($(window).height() * 0.4 - 45),
            collapseDepth: Number('0'),
            headingSelector: 'h2, h3, h4'
        });

        // modify the toc link href to support Chinese.
        let i = 0;
        let tocHeading = 'toc-heading-';
        $('#toc-content a').each(function () {
            $(this).attr('href', '#' + tocHeading + (++i));
        });

        // modify the heading title id to support Chinese.
        i = 0;
        $('#articleContent').children('h2, h3, h4').each(function () {
            $(this).attr('id', tocHeading + (++i));
        });

        // Set scroll toc fixed.
        let tocHeight = parseInt($(window).height() * 0.4 - 64);
        let $tocWidget = $('.toc-widget');
        $(window).scroll(function () {
            let scroll = $(window).scrollTop();
            /* add post toc fixed. */
            if (scroll > tocHeight) {
                $tocWidget.addClass('toc-fixed');
            } else {
                $tocWidget.removeClass('toc-fixed');
            }
        });

        
        /* 修复文章卡片 div 的宽度. */
        let fixPostCardWidth = function (srcId, targetId) {
            let srcDiv = $('#' + srcId);
            if (srcDiv.length === 0) {
                return;
            }

            let w = srcDiv.width();
            if (w >= 450) {
                w = w + 21;
            } else if (w >= 350 && w < 450) {
                w = w + 18;
            } else if (w >= 300 && w < 350) {
                w = w + 16;
            } else {
                w = w + 14;
            }
            $('#' + targetId).width(w);
        };

        // 切换TOC目录展开收缩的相关操作.
        const expandedClass = 'expanded';
        let $tocAside = $('#toc-aside');
        let $mainContent = $('#main-content');
        $('#floating-toc-btn .btn-floating').click(function () {
            if ($tocAside.hasClass(expandedClass)) {
                $tocAside.removeClass(expandedClass).hide();
                $mainContent.removeClass('l9');
            } else {
                $tocAside.addClass(expandedClass).show();
                $mainContent.addClass('l9');
            }
            fixPostCardWidth('artDetail', 'prenext-posts');
        });
        
    });
</script>

    

</main>




    <footer class="page-footer bg-color">
    
        <link rel="stylesheet" href="/libs/aplayer/APlayer.min.css">
<style>
    .aplayer .aplayer-lrc p {
        
        display: none;
        
        font-size: 12px;
        font-weight: 700;
        line-height: 16px !important;
    }

    .aplayer .aplayer-lrc p.aplayer-lrc-current {
        
        display: none;
        
        font-size: 15px;
        color: #42b983;
    }

    
</style>
<div class="">
    
    <div class="row">
        <meting-js class="col l8 offset-l2 m10 offset-m1 s12"
                   server="netease"
                   type="playlist"
                   id="113118807"
                   fixed='true'
                   autoplay='false'
                   theme='#42b983'
                   loop='all'
                   order='random'
                   preload='auto'
                   volume='0.7'
                   list-folded='true'
        >
        </meting-js>
    </div>
</div>

<script src="/libs/aplayer/APlayer.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/meting@2/dist/Meting.min.js"></script>

    
    <div class="container row center-align" style="margin-bottom: 0px !important;">
        <div class="col s12 m8 l8 copy-right">
            Copyright&nbsp;&copy;
            
                <span id="year">2019-2024</span>
            
            <span id="year">2019</span>
            <a href="/about" target="_blank">JIANG XIAOFAN</a>
            |&nbsp;Powered by&nbsp;<a href="https://hexo.io/" target="_blank">Hexo</a>
            |&nbsp;Theme&nbsp;<a href="https://github.com/blinkfox/hexo-theme-matery" target="_blank">Matery</a>
            <br>
            
            &nbsp;<i class="fas fa-chart-area"></i>&nbsp;站点总字数:&nbsp;<span
                class="white-color">107k</span>&nbsp;字
            
            
            
            
            
            
            <span id="busuanzi_container_site_pv">
                |&nbsp;<i class="far fa-eye"></i>&nbsp;总访问量:&nbsp;<span id="busuanzi_value_site_pv"
                    class="white-color"></span>&nbsp;次
            </span>
            
            
            <span id="busuanzi_container_site_uv">
                |&nbsp;<i class="fas fa-users"></i>&nbsp;总访问人数:&nbsp;<span id="busuanzi_value_site_uv"
                    class="white-color"></span>&nbsp;人
            </span>
            
            <br>
            
            <br>
            
        </div>
        <div class="col s12 m4 l4 social-link social-statis">
    <a href="https://github.com/blinkfox" class="tooltipped" target="_blank" data-tooltip="访问我的GitHub" data-position="top" data-delay="50">
        <i class="fab fa-github"></i>
    </a>















    <a href="/atom.xml" class="tooltipped" target="_blank" data-tooltip="RSS 订阅" data-position="top" data-delay="50">
        <i class="fas fa-rss"></i>
    </a>

</div>
    </div>
</footer>

<div class="progress-bar"></div>


    <!-- 搜索遮罩框 -->
<div id="searchModal" class="modal">
    <div class="modal-content">
        <div class="search-header">
            <span class="title"><i class="fas fa-search"></i>&nbsp;&nbsp;搜索</span>
            <input type="search" id="searchInput" name="s" placeholder="请输入搜索的关键字"
                   class="search-input">
        </div>
        <div id="searchResult"></div>
    </div>
</div>

<script type="text/javascript">
$(function () {
    var searchFunc = function (path, search_id, content_id) {
        'use strict';
        $.ajax({
            url: path,
            dataType: "xml",
            success: function (xmlResponse) {
                // get the contents from search data
                var datas = $("entry", xmlResponse).map(function () {
                    return {
                        title: $("title", this).text(),
                        content: $("content", this).text(),
                        url: $("url", this).text()
                    };
                }).get();
                var $input = document.getElementById(search_id);
                var $resultContent = document.getElementById(content_id);
                $input.addEventListener('input', function () {
                    var str = '<ul class=\"search-result-list\">';
                    var keywords = this.value.trim().toLowerCase().split(/[\s\-]+/);
                    $resultContent.innerHTML = "";
                    if (this.value.trim().length <= 0) {
                        return;
                    }
                    // perform local searching
                    datas.forEach(function (data) {
                        var isMatch = true;
                        var data_title = data.title.trim().toLowerCase();
                        var data_content = data.content.trim().replace(/<[^>]+>/g, "").toLowerCase();
                        var data_url = data.url;
                        data_url = data_url.indexOf('/') === 0 ? data.url : '/' + data_url;
                        var index_title = -1;
                        var index_content = -1;
                        var first_occur = -1;
                        // only match artiles with not empty titles and contents
                        if (data_title !== '' && data_content !== '') {
                            keywords.forEach(function (keyword, i) {
                                index_title = data_title.indexOf(keyword);
                                index_content = data_content.indexOf(keyword);
                                if (index_title < 0 && index_content < 0) {
                                    isMatch = false;
                                } else {
                                    if (index_content < 0) {
                                        index_content = 0;
                                    }
                                    if (i === 0) {
                                        first_occur = index_content;
                                    }
                                }
                            });
                        }
                        // show search results
                        if (isMatch) {
                            str += "<li><a href='" + data_url + "' class='search-result-title'>" + data_title + "</a>";
                            var content = data.content.trim().replace(/<[^>]+>/g, "");
                            if (first_occur >= 0) {
                                // cut out 100 characters
                                var start = first_occur - 20;
                                var end = first_occur + 80;
                                if (start < 0) {
                                    start = 0;
                                }
                                if (start === 0) {
                                    end = 100;
                                }
                                if (end > content.length) {
                                    end = content.length;
                                }
                                var match_content = content.substr(start, end);
                                // highlight all keywords
                                keywords.forEach(function (keyword) {
                                    var regS = new RegExp(keyword, "gi");
                                    match_content = match_content.replace(regS, "<em class=\"search-keyword\">" + keyword + "</em>");
                                });

                                str += "<p class=\"search-result\">" + match_content + "...</p>"
                            }
                            str += "</li>";
                        }
                    });
                    str += "</ul>";
                    $resultContent.innerHTML = str;
                });
            }
        });
    };

    searchFunc('/search.xml', 'searchInput', 'searchResult');
});
</script>

    <!-- 回到顶部按钮 -->
<div id="backTop" class="top-scroll">
    <a class="btn-floating btn-large waves-effect waves-light" href="#!">
        <i class="fas fa-arrow-up"></i>
    </a>
</div>


    <script src="/libs/materialize/materialize.min.js"></script>
    <script src="/libs/masonry/masonry.pkgd.min.js"></script>
    <script src="/libs/aos/aos.js"></script>
    <script src="/libs/scrollprogress/scrollProgress.min.js"></script>
    <script src="/libs/lightGallery/js/lightgallery-all.min.js"></script>
    <script src="/js/matery.js"></script>

    <!-- Baidu Analytics -->

    <!-- Baidu Push -->

<script>
    (function () {
        var bp = document.createElement('script');
        var curProtocol = window.location.protocol.split(':')[0];
        if (curProtocol === 'https') {
            bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
        } else {
            bp.src = 'http://push.zhanzhang.baidu.com/push.js';
        }
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(bp, s);
    })();
</script>

    
    <script src="/libs/others/clicklove.js" async="async"></script>
    
    
    <script async src="/libs/others/busuanzi.pure.mini.js"></script>
    

    

    

	
    

    

    

    
    <script src="/libs/instantpage/instantpage.js" type="module"></script>
    

</body>

</html>
